From d5ea65afdd9ca46726621b4fe851a6580ab73a52 Mon Sep 17 00:00:00 2001 From: Anatolii Bazko Date: Mon, 25 Jan 2021 13:48:06 +0200 Subject: [PATCH] Specify resources limits (#612) * Specify resource limits Signed-off-by: Anatolii Bazko --- .vscode/tasks.json | 6 +- README.md | 4 +- deploy/crds/org_v1_che_crd.yaml | 98 ++++++++++++++- .../che-operator.clusterserviceversion.yaml | 14 ++- .../manifests/org_v1_che_crd.yaml | 98 ++++++++++++++- .../che-operator.clusterserviceversion.yaml | 14 ++- .../manifests/org_v1_che_crd.yaml | 98 ++++++++++++++- deploy/operator.yaml | 7 ++ go.mod | 3 +- go.sum | 4 - pkg/apis/org/v1/che_types.go | 69 ++++++++-- pkg/apis/org/v1/zz_generated.deepcopy.go | 36 ++++++ pkg/controller/che/che_controller_test.go | 2 +- pkg/deploy/defaults.go | 56 ++++++--- pkg/deploy/devfile-registry/deployment.go | 51 ++++++-- .../devfile-registry/deployment_test.go | 113 +++++++++++++++++ pkg/deploy/devfile-registry/init_test.go | 21 ++++ .../identity-provider/deployment_keycloak.go | 23 ++-- .../deployment_keycloak_test.go | 119 ++++++++++++++++++ pkg/deploy/identity-provider/init_test.go | 21 ++++ pkg/deploy/plugin-registry/deployment.go | 51 ++++++-- pkg/deploy/plugin-registry/deployment_test.go | 113 +++++++++++++++++ pkg/deploy/plugin-registry/init_test.go | 21 ++++ .../postgres/deployment_posgres_test.go | 119 ++++++++++++++++++ pkg/deploy/postgres/deployment_postgres.go | 19 ++- pkg/deploy/postgres/init_test.go | 21 ++++ pkg/deploy/registry/registry.go | 13 +- pkg/deploy/server/deployment_che.go | 21 ++-- pkg/deploy/server/deployment_che_test.go | 112 +++++++++++++++++ pkg/util/test_util.go | 69 ++++++++++ pkg/util/util.go | 8 ++ 31 files changed, 1306 insertions(+), 118 deletions(-) create mode 100644 pkg/deploy/devfile-registry/deployment_test.go create mode 100644 pkg/deploy/devfile-registry/init_test.go create mode 100644 pkg/deploy/identity-provider/deployment_keycloak_test.go create mode 100644 pkg/deploy/identity-provider/init_test.go create mode 100644 pkg/deploy/plugin-registry/deployment_test.go create mode 100644 pkg/deploy/plugin-registry/init_test.go create mode 100644 pkg/deploy/postgres/deployment_posgres_test.go create mode 100644 pkg/deploy/postgres/init_test.go create mode 100644 pkg/deploy/server/deployment_che_test.go create mode 100644 pkg/util/test_util.go diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 58de5793a..f9e5605ee 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -74,7 +74,7 @@ "group": "build" }, { - "label": "Update cr/crd files", + "label": "Update crd files", "command": "./olm/update-crd-files.sh", "type": "shell", "args": [], @@ -87,8 +87,8 @@ "group": "build" }, { - "label": "Update OLM bundle files", - "command": "./olm/update-crd-files.sh && ./olm/update-nightly-bundle.sh", + "label": "Update nightly OLM bundle", + "command": "./olm/update-nightly-bundle.sh", "type": "shell", "args": [], "problemMatcher": [ diff --git a/README.md b/README.md index 7554a2a83..5ed362159 100644 --- a/README.md +++ b/README.md @@ -306,7 +306,7 @@ New golang dependencies in the vendor folder should be committed and included in ### Updating Custom Resource Definition file Che cluster custom resource definition (CRD) defines Eclipse CheCluster custom resource object. It contains information about object structure, field types, field descriptions. -CRD file is a YAML definition located in the `deploy/crds/org_v1_che_crd.yaml`. The file is auto-generated, so do not edit it directly to update it. If you want to add new fields or fix descriptions in the CRD, make your changes in the file `pkg/apis/org/v1/che_types.go` and run VSCode task `Update cr/crd files` or use the terminal +CRD file is a YAML definition located in the `deploy/crds/org_v1_che_crd.yaml`. The file is auto-generated, so do not edit it directly to update it. If you want to add new fields or fix descriptions in the CRD, make your changes in the file `pkg/apis/org/v1/che_types.go` and run VSCode task `Update crd files` or use the terminal ```bash $ olm/update-crd-files.sh @@ -328,7 +328,7 @@ Sometimes, during development, you need to modify some YAML definitions in the ` - Che cluster custom resource definition `pkg/apis/org/v1/che_types.go`. For example you want to fix some properties description or apply new Che type properties with default values. These changes affect CRD `deploy/crds/org_v1_che_crd.yaml`. - add Openshift ui annotations for Che types properties (`pkg/apis/org/v1/che_types.go`) to display information or interactive elements on the Openshift user interface. -For all these cases it's a necessary to generate a new OLM bundle to make these changes working with OLM. Run the VSCode tasks `Update OLM bundle files` or use the terminal: +For all these cases it's a necessary to generate a new OLM bundle to make these changes working with OLM. Run the VSCode tasks `Update nightly OLM bundle` or use the terminal: ```bash $ olm/update-nightly-bundle.sh diff --git a/deploy/crds/org_v1_che_crd.yaml b/deploy/crds/org_v1_che_crd.yaml index d50ff307a..fc0d9cb6a 100644 --- a/deploy/crds/org_v1_che_crd.yaml +++ b/deploy/crds/org_v1_che_crd.yaml @@ -71,6 +71,34 @@ spec: field). If omitted or left blank, it will be set to the value of the `flavour` field suffixed with `-public`. type: string + identityProviderContainerResources: + description: Identity provider container custom settings + properties: + limits: + description: Limits describes the maximum amount of compute + resources allowed. + properties: + cpu: + description: CPU, in cores. (500m = .5 cores) + type: string + memory: + description: Memory, in bytes. (500Gi = 500GiB = 500 * 1024 + * 1024 * 1024) + type: string + type: object + request: + description: Requests describes the minimum amount of compute + resources required. + properties: + cpu: + description: CPU, in cores. (500m = .5 cores) + type: string + memory: + description: Memory, in bytes. (500Gi = 500GiB = 500 * 1024 + * 1024 * 1024) + type: string + type: object + type: object identityProviderImage: description: Overrides the container image used in the Identity Provider (Keycloak / RH SSO) deployment. This includes the image @@ -178,6 +206,34 @@ spec: description: Configuration settings related to the database used by the Che installation. properties: + chePostgresContainerResources: + description: Postgres container custom settings + properties: + limits: + description: Limits describes the maximum amount of compute + resources allowed. + properties: + cpu: + description: CPU, in cores. (500m = .5 cores) + type: string + memory: + description: Memory, in bytes. (500Gi = 500GiB = 500 * 1024 + * 1024 * 1024) + type: string + type: object + request: + description: Requests describes the minimum amount of compute + resources required. + properties: + cpu: + description: CPU, in cores. (500m = .5 cores) + type: string + memory: + description: Memory, in bytes. (500Gi = 500GiB = 500 * 1024 + * 1024 * 1024) + type: string + type: object + type: object chePostgresDb: description: Postgres database name that the Che server uses to connect to the DB. Defaults to `dbche`. @@ -431,6 +487,14 @@ spec: config map from other CR fields, then the value defined in the `customCheProperties` will be used instead. type: object + devfileRegistryCpuLimit: + description: Overrides the cpu limit used in the Devfile registry + deployment. In cores. (500m = .5 cores). Default to 500m. + type: string + devfileRegistryCpuRequest: + description: Overrides the cpu request used in the Devfile registry + deployment. In cores. (500m = .5 cores). Default to 100m. + type: string devfileRegistryImage: description: Overrides the container image used in the Devfile registry deployment. This includes the image tag. Omit it or leave it empty @@ -446,11 +510,13 @@ spec: type: object devfileRegistryMemoryLimit: description: Overrides the memory limit used in the Devfile registry - deployment. Defaults to 256Mi. + deployment. In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). + Defaults to 256Mi. type: string devfileRegistryMemoryRequest: description: Overrides the memory request used in the Devfile registry - deployment. Defaults to 16Mi. + deployment In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). + Defaults to 32Mi. type: string devfileRegistryPullPolicy: description: Overrides the image pull policy used in the Devfile @@ -502,6 +568,14 @@ spec: doc https://docs.openshift.com/container-platform/4.4/networking/enable-cluster-wide-proxy.html) (see also the `proxyURL` fields).' type: string + pluginRegistryCpuLimit: + description: Overrides the cpu limit used in the Plugin registry + deployment. In cores. (500m = .5 cores). Default to 500m. + type: string + pluginRegistryCpuRequest: + description: Overrides the cpu request used in the Plugin registry + deployment. In cores. (500m = .5 cores). Default to 100m. + type: string pluginRegistryImage: description: Overrides the container image used in the Plugin registry deployment. This includes the image tag. Omit it or leave it empty @@ -517,11 +591,13 @@ spec: type: object pluginRegistryMemoryLimit: description: Overrides the memory limit used in the Plugin registry - deployment. Defaults to 256Mi. + deployment. In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). + Defaults to 256Mi. type: string pluginRegistryMemoryRequest: description: Overrides the memory request used in the Plugin registry - deployment. Defaults to 16Mi. + deployment. In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). + Defaults to 32Mi. type: string pluginRegistryPullPolicy: description: Overrides the image pull policy used in the Plugin @@ -579,6 +655,14 @@ spec: operator will automatically detect if router certificate is self-signed. If so it will be propagated to Che server and some other components. type: boolean + serverCpuLimit: + description: Overrides the cpu limit used in the Che server deployment + In cores. (500m = .5 cores). Default to 1. + type: string + serverCpuRequest: + description: Overrides the cpu request used in the Che server deployment + In cores. (500m = .5 cores). Default to 100m. + type: string serverExposureStrategy: description: Sets the server and workspaces exposure type. Possible values are "multi-host", "single-host", "default-host". Defaults @@ -594,11 +678,13 @@ spec: type: string serverMemoryLimit: description: Overrides the memory limit used in the Che server deployment. - Defaults to 1Gi. + In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). Defaults + to 1Gi. type: string serverMemoryRequest: description: Overrides the memory request used in the Che server - deployment. Defaults to 512Mi. + deployment. In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). + Defaults to 512Mi. type: string serverTrustStoreConfigMapName: description: Name of the config-map with public certificates to diff --git a/deploy/olm-catalog/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml b/deploy/olm-catalog/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml index acb95c6e4..0a945d643 100644 --- a/deploy/olm-catalog/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml +++ b/deploy/olm-catalog/eclipse-che-preview-kubernetes/manifests/che-operator.clusterserviceversion.yaml @@ -84,13 +84,13 @@ metadata: categories: Developer Tools certified: "false" containerImage: quay.io/eclipse/che-operator:nightly - createdAt: "2021-01-15T13:55:16Z" + createdAt: "2021-01-25T10:14:35Z" description: A Kube-native development solution that delivers portable and collaborative developer workspaces. operatorframework.io/suggested-namespace: eclipse-che repository: https://github.com/eclipse/che-operator support: Eclipse Foundation - name: eclipse-che-preview-kubernetes.v7.25.0-70.nightly + name: eclipse-che-preview-kubernetes.v7.25.0-82.nightly namespace: placeholder spec: apiservicedefinitions: {} @@ -381,7 +381,13 @@ spec: periodSeconds: 10 successThreshold: 1 timeoutSeconds: 5 - resources: {} + resources: + limits: + cpu: 500m + memory: 256Mi + requests: + cpu: 100m + memory: 64Mi securityContext: capabilities: drop: @@ -518,4 +524,4 @@ spec: maturity: stable provider: name: Eclipse Foundation - version: 7.25.0-70.nightly + version: 7.25.0-82.nightly diff --git a/deploy/olm-catalog/eclipse-che-preview-kubernetes/manifests/org_v1_che_crd.yaml b/deploy/olm-catalog/eclipse-che-preview-kubernetes/manifests/org_v1_che_crd.yaml index d50ff307a..fc0d9cb6a 100644 --- a/deploy/olm-catalog/eclipse-che-preview-kubernetes/manifests/org_v1_che_crd.yaml +++ b/deploy/olm-catalog/eclipse-che-preview-kubernetes/manifests/org_v1_che_crd.yaml @@ -71,6 +71,34 @@ spec: field). If omitted or left blank, it will be set to the value of the `flavour` field suffixed with `-public`. type: string + identityProviderContainerResources: + description: Identity provider container custom settings + properties: + limits: + description: Limits describes the maximum amount of compute + resources allowed. + properties: + cpu: + description: CPU, in cores. (500m = .5 cores) + type: string + memory: + description: Memory, in bytes. (500Gi = 500GiB = 500 * 1024 + * 1024 * 1024) + type: string + type: object + request: + description: Requests describes the minimum amount of compute + resources required. + properties: + cpu: + description: CPU, in cores. (500m = .5 cores) + type: string + memory: + description: Memory, in bytes. (500Gi = 500GiB = 500 * 1024 + * 1024 * 1024) + type: string + type: object + type: object identityProviderImage: description: Overrides the container image used in the Identity Provider (Keycloak / RH SSO) deployment. This includes the image @@ -178,6 +206,34 @@ spec: description: Configuration settings related to the database used by the Che installation. properties: + chePostgresContainerResources: + description: Postgres container custom settings + properties: + limits: + description: Limits describes the maximum amount of compute + resources allowed. + properties: + cpu: + description: CPU, in cores. (500m = .5 cores) + type: string + memory: + description: Memory, in bytes. (500Gi = 500GiB = 500 * 1024 + * 1024 * 1024) + type: string + type: object + request: + description: Requests describes the minimum amount of compute + resources required. + properties: + cpu: + description: CPU, in cores. (500m = .5 cores) + type: string + memory: + description: Memory, in bytes. (500Gi = 500GiB = 500 * 1024 + * 1024 * 1024) + type: string + type: object + type: object chePostgresDb: description: Postgres database name that the Che server uses to connect to the DB. Defaults to `dbche`. @@ -431,6 +487,14 @@ spec: config map from other CR fields, then the value defined in the `customCheProperties` will be used instead. type: object + devfileRegistryCpuLimit: + description: Overrides the cpu limit used in the Devfile registry + deployment. In cores. (500m = .5 cores). Default to 500m. + type: string + devfileRegistryCpuRequest: + description: Overrides the cpu request used in the Devfile registry + deployment. In cores. (500m = .5 cores). Default to 100m. + type: string devfileRegistryImage: description: Overrides the container image used in the Devfile registry deployment. This includes the image tag. Omit it or leave it empty @@ -446,11 +510,13 @@ spec: type: object devfileRegistryMemoryLimit: description: Overrides the memory limit used in the Devfile registry - deployment. Defaults to 256Mi. + deployment. In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). + Defaults to 256Mi. type: string devfileRegistryMemoryRequest: description: Overrides the memory request used in the Devfile registry - deployment. Defaults to 16Mi. + deployment In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). + Defaults to 32Mi. type: string devfileRegistryPullPolicy: description: Overrides the image pull policy used in the Devfile @@ -502,6 +568,14 @@ spec: doc https://docs.openshift.com/container-platform/4.4/networking/enable-cluster-wide-proxy.html) (see also the `proxyURL` fields).' type: string + pluginRegistryCpuLimit: + description: Overrides the cpu limit used in the Plugin registry + deployment. In cores. (500m = .5 cores). Default to 500m. + type: string + pluginRegistryCpuRequest: + description: Overrides the cpu request used in the Plugin registry + deployment. In cores. (500m = .5 cores). Default to 100m. + type: string pluginRegistryImage: description: Overrides the container image used in the Plugin registry deployment. This includes the image tag. Omit it or leave it empty @@ -517,11 +591,13 @@ spec: type: object pluginRegistryMemoryLimit: description: Overrides the memory limit used in the Plugin registry - deployment. Defaults to 256Mi. + deployment. In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). + Defaults to 256Mi. type: string pluginRegistryMemoryRequest: description: Overrides the memory request used in the Plugin registry - deployment. Defaults to 16Mi. + deployment. In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). + Defaults to 32Mi. type: string pluginRegistryPullPolicy: description: Overrides the image pull policy used in the Plugin @@ -579,6 +655,14 @@ spec: operator will automatically detect if router certificate is self-signed. If so it will be propagated to Che server and some other components. type: boolean + serverCpuLimit: + description: Overrides the cpu limit used in the Che server deployment + In cores. (500m = .5 cores). Default to 1. + type: string + serverCpuRequest: + description: Overrides the cpu request used in the Che server deployment + In cores. (500m = .5 cores). Default to 100m. + type: string serverExposureStrategy: description: Sets the server and workspaces exposure type. Possible values are "multi-host", "single-host", "default-host". Defaults @@ -594,11 +678,13 @@ spec: type: string serverMemoryLimit: description: Overrides the memory limit used in the Che server deployment. - Defaults to 1Gi. + In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). Defaults + to 1Gi. type: string serverMemoryRequest: description: Overrides the memory request used in the Che server - deployment. Defaults to 512Mi. + deployment. In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). + Defaults to 512Mi. type: string serverTrustStoreConfigMapName: description: Name of the config-map with public certificates to diff --git a/deploy/olm-catalog/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml b/deploy/olm-catalog/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml index ae79b55dc..fbaabd1b2 100644 --- a/deploy/olm-catalog/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml +++ b/deploy/olm-catalog/eclipse-che-preview-openshift/manifests/che-operator.clusterserviceversion.yaml @@ -75,13 +75,13 @@ metadata: categories: Developer Tools, OpenShift Optional certified: "false" containerImage: quay.io/eclipse/che-operator:nightly - createdAt: "2021-01-15T13:55:25Z" + createdAt: "2021-01-25T10:14:44Z" description: A Kube-native development solution that delivers portable and collaborative developer workspaces in OpenShift. operatorframework.io/suggested-namespace: eclipse-che repository: https://github.com/eclipse/che-operator support: Eclipse Foundation - name: eclipse-che-preview-openshift.v7.25.0-70.nightly + name: eclipse-che-preview-openshift.v7.25.0-82.nightly namespace: placeholder spec: apiservicedefinitions: {} @@ -394,7 +394,13 @@ spec: periodSeconds: 10 successThreshold: 1 timeoutSeconds: 5 - resources: {} + resources: + limits: + cpu: 500m + memory: 256Mi + requests: + cpu: 100m + memory: 64Mi securityContext: capabilities: drop: @@ -537,4 +543,4 @@ spec: maturity: stable provider: name: Eclipse Foundation - version: 7.25.0-70.nightly + version: 7.25.0-82.nightly diff --git a/deploy/olm-catalog/eclipse-che-preview-openshift/manifests/org_v1_che_crd.yaml b/deploy/olm-catalog/eclipse-che-preview-openshift/manifests/org_v1_che_crd.yaml index bc4c6efe8..3f7ee6316 100644 --- a/deploy/olm-catalog/eclipse-che-preview-openshift/manifests/org_v1_che_crd.yaml +++ b/deploy/olm-catalog/eclipse-che-preview-openshift/manifests/org_v1_che_crd.yaml @@ -72,6 +72,34 @@ spec: field). If omitted or left blank, it will be set to the value of the `flavour` field suffixed with `-public`. type: string + identityProviderContainerResources: + description: Identity provider container custom settings + properties: + limits: + description: Limits describes the maximum amount of compute + resources allowed. + properties: + cpu: + description: CPU, in cores. (500m = .5 cores) + type: string + memory: + description: Memory, in bytes. (500Gi = 500GiB = 500 * 1024 + * 1024 * 1024) + type: string + type: object + request: + description: Requests describes the minimum amount of compute + resources required. + properties: + cpu: + description: CPU, in cores. (500m = .5 cores) + type: string + memory: + description: Memory, in bytes. (500Gi = 500GiB = 500 * 1024 + * 1024 * 1024) + type: string + type: object + type: object identityProviderImage: description: Overrides the container image used in the Identity Provider (Keycloak / RH SSO) deployment. This includes the image @@ -179,6 +207,34 @@ spec: description: Configuration settings related to the database used by the Che installation. properties: + chePostgresContainerResources: + description: Postgres container custom settings + properties: + limits: + description: Limits describes the maximum amount of compute + resources allowed. + properties: + cpu: + description: CPU, in cores. (500m = .5 cores) + type: string + memory: + description: Memory, in bytes. (500Gi = 500GiB = 500 * 1024 + * 1024 * 1024) + type: string + type: object + request: + description: Requests describes the minimum amount of compute + resources required. + properties: + cpu: + description: CPU, in cores. (500m = .5 cores) + type: string + memory: + description: Memory, in bytes. (500Gi = 500GiB = 500 * 1024 + * 1024 * 1024) + type: string + type: object + type: object chePostgresDb: description: Postgres database name that the Che server uses to connect to the DB. Defaults to `dbche`. @@ -432,6 +488,14 @@ spec: config map from other CR fields, then the value defined in the `customCheProperties` will be used instead. type: object + devfileRegistryCpuLimit: + description: Overrides the cpu limit used in the Devfile registry + deployment. In cores. (500m = .5 cores). Default to 500m. + type: string + devfileRegistryCpuRequest: + description: Overrides the cpu request used in the Devfile registry + deployment. In cores. (500m = .5 cores). Default to 100m. + type: string devfileRegistryImage: description: Overrides the container image used in the Devfile registry deployment. This includes the image tag. Omit it or leave it empty @@ -447,11 +511,13 @@ spec: type: object devfileRegistryMemoryLimit: description: Overrides the memory limit used in the Devfile registry - deployment. Defaults to 256Mi. + deployment. In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). + Defaults to 256Mi. type: string devfileRegistryMemoryRequest: description: Overrides the memory request used in the Devfile registry - deployment. Defaults to 16Mi. + deployment In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). + Defaults to 32Mi. type: string devfileRegistryPullPolicy: description: Overrides the image pull policy used in the Devfile @@ -503,6 +569,14 @@ spec: doc https://docs.openshift.com/container-platform/4.4/networking/enable-cluster-wide-proxy.html) (see also the `proxyURL` fields).' type: string + pluginRegistryCpuLimit: + description: Overrides the cpu limit used in the Plugin registry + deployment. In cores. (500m = .5 cores). Default to 500m. + type: string + pluginRegistryCpuRequest: + description: Overrides the cpu request used in the Plugin registry + deployment. In cores. (500m = .5 cores). Default to 100m. + type: string pluginRegistryImage: description: Overrides the container image used in the Plugin registry deployment. This includes the image tag. Omit it or leave it empty @@ -518,11 +592,13 @@ spec: type: object pluginRegistryMemoryLimit: description: Overrides the memory limit used in the Plugin registry - deployment. Defaults to 256Mi. + deployment. In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). + Defaults to 256Mi. type: string pluginRegistryMemoryRequest: description: Overrides the memory request used in the Plugin registry - deployment. Defaults to 16Mi. + deployment. In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). + Defaults to 32Mi. type: string pluginRegistryPullPolicy: description: Overrides the image pull policy used in the Plugin @@ -580,6 +656,14 @@ spec: operator will automatically detect if router certificate is self-signed. If so it will be propagated to Che server and some other components. type: boolean + serverCpuLimit: + description: Overrides the cpu limit used in the Che server deployment + In cores. (500m = .5 cores). Default to 1. + type: string + serverCpuRequest: + description: Overrides the cpu request used in the Che server deployment + In cores. (500m = .5 cores). Default to 100m. + type: string serverExposureStrategy: description: Sets the server and workspaces exposure type. Possible values are "multi-host", "single-host", "default-host". Defaults @@ -595,11 +679,13 @@ spec: type: string serverMemoryLimit: description: Overrides the memory limit used in the Che server deployment. - Defaults to 1Gi. + In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). Defaults + to 1Gi. type: string serverMemoryRequest: description: Overrides the memory request used in the Che server - deployment. Defaults to 512Mi. + deployment. In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). + Defaults to 512Mi. type: string serverTrustStoreConfigMapName: description: Name of the config-map with public certificates to diff --git a/deploy/operator.yaml b/deploy/operator.yaml index 89b65625c..45cf23175 100644 --- a/deploy/operator.yaml +++ b/deploy/operator.yaml @@ -111,6 +111,13 @@ spec: capabilities: drop: - ALL + resources: + requests: + memory: 64Mi + cpu: 100m + limits: + memory: 256Mi + cpu: 500m restartPolicy: Always serviceAccountName: che-operator terminationGracePeriodSeconds: 5 diff --git a/go.mod b/go.mod index 091fd8ffc..92a678288 100644 --- a/go.mod +++ b/go.mod @@ -12,11 +12,11 @@ require ( github.com/prometheus/common v0.7.0 github.com/sirupsen/logrus v1.4.2 golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914 - gopkg.in/yaml.v2 v2.2.8 k8s.io/api v0.18.2 k8s.io/apimachinery v0.18.2 k8s.io/client-go v12.0.0+incompatible sigs.k8s.io/controller-runtime v0.6.0 + sigs.k8s.io/yaml v1.2.0 ) // Pinned to kubernetes-1.16.2 @@ -43,6 +43,7 @@ replace ( k8s.io/metrics => k8s.io/metrics v0.0.0-20191016113814-3b1a734dba6e k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.0.0-20191016112829-06bb3c9d77c9 sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.4.0 + sigs.k8s.io/yaml => sigs.k8s.io/yaml v1.1.0 ) replace github.com/docker/docker => github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309 // Required by Helm diff --git a/go.sum b/go.sum index 4dcbdf7d7..2ce30314e 100644 --- a/go.sum +++ b/go.sum @@ -1069,8 +1069,6 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= @@ -1159,6 +1157,4 @@ sigs.k8s.io/testing_frameworks v0.1.2 h1:vK0+tvjF0BZ/RYFeZ1E6BYBwHJJXhjuZ3TdsEKH sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= diff --git a/pkg/apis/org/v1/che_types.go b/pkg/apis/org/v1/che_types.go index 45221df8f..00ae4ee19 100644 --- a/pkg/apis/org/v1/che_types.go +++ b/pkg/apis/org/v1/che_types.go @@ -168,12 +168,22 @@ type CheClusterSpecServer struct { // Default value is `Always` for `nightly` or `latest` images, and `IfNotPresent` in other cases. // +optional DevfileRegistryPullPolicy corev1.PullPolicy `json:"devfileRegistryPullPolicy,omitempty"` - // Overrides the memory limit used in the Devfile registry deployment. Defaults to 256Mi. + // Overrides the memory limit used in the Devfile registry deployment. + // In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). Defaults to 256Mi. // +optional DevfileRegistryMemoryLimit string `json:"devfileRegistryMemoryLimit,omitempty"` - // Overrides the memory request used in the Devfile registry deployment. Defaults to 16Mi. + // Overrides the memory request used in the Devfile registry deployment + // In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). Defaults to 32Mi. // +optional DevfileRegistryMemoryRequest string `json:"devfileRegistryMemoryRequest,omitempty"` + // Overrides the cpu limit used in the Devfile registry deployment. + // In cores. (500m = .5 cores). Default to 500m. + // +optional + DevfileRegistryCpuLimit string `json:"devfileRegistryCpuLimit,omitempty"` + // Overrides the cpu request used in the Devfile registry deployment. + // In cores. (500m = .5 cores). Default to 100m. + // +optional + DevfileRegistryCpuRequest string `json:"devfileRegistryCpuRequest,omitempty"` // Devfile registry ingress custom settings // +optional DevfileRegistryIngress IngressCustomSettings `json:"devfileRegistryIngress,omitempty"` @@ -199,12 +209,22 @@ type CheClusterSpecServer struct { // Default value is `Always` for `nightly` or `latest` images, and `IfNotPresent` in other cases. // +optional PluginRegistryPullPolicy corev1.PullPolicy `json:"pluginRegistryPullPolicy,omitempty"` - // Overrides the memory limit used in the Plugin registry deployment. Defaults to 256Mi. + // Overrides the memory limit used in the Plugin registry deployment. + // In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). Defaults to 256Mi. // +optional PluginRegistryMemoryLimit string `json:"pluginRegistryMemoryLimit,omitempty"` - // Overrides the memory request used in the Plugin registry deployment. Defaults to 16Mi. + // Overrides the memory request used in the Plugin registry deployment. + // In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). Defaults to 32Mi. // +optional PluginRegistryMemoryRequest string `json:"pluginRegistryMemoryRequest,omitempty"` + // Overrides the cpu limit used in the Plugin registry deployment. + // In cores. (500m = .5 cores). Default to 500m. + // +optional + PluginRegistryCpuLimit string `json:"pluginRegistryCpuLimit,omitempty"` + // Overrides the cpu request used in the Plugin registry deployment. + // In cores. (500m = .5 cores). Default to 100m. + // +optional + PluginRegistryCpuRequest string `json:"pluginRegistryCpuRequest,omitempty"` // Plugin registry ingress custom settings // +optional PluginRegistryIngress IngressCustomSettings `json:"pluginRegistryIngress,omitempty"` @@ -260,13 +280,22 @@ type CheClusterSpecServer struct { // If the secret is defined then `proxyUser` and `proxyPassword` are ignored // +optional ProxySecret string `json:"proxySecret,omitempty"` - // Overrides the memory request used in the Che server deployment. Defaults to 512Mi. + // Overrides the memory request used in the Che server deployment. + // In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). Defaults to 512Mi. // +optional ServerMemoryRequest string `json:"serverMemoryRequest,omitempty"` - // Overrides the memory limit used in the Che server deployment. Defaults to 1Gi. + // Overrides the memory limit used in the Che server deployment. + // In bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024). Defaults to 1Gi. // +optional ServerMemoryLimit string `json:"serverMemoryLimit,omitempty"` - + // Overrides the cpu limit used in the Che server deployment + // In cores. (500m = .5 cores). Default to 1. + // +optional + ServerCpuLimit string `json:"serverCpuLimit,omitempty"` + // Overrides the cpu request used in the Che server deployment + // In cores. (500m = .5 cores). Default to 100m. + // +optional + ServerCpuRequest string `json:"serverCpuRequest,omitempty"` // Sets the server and workspaces exposure type. Possible values are "multi-host", "single-host", "default-host". // Defaults to "multi-host" which creates a separate ingress (or route on OpenShift) for every required // endpoint. @@ -345,6 +374,9 @@ type CheClusterSpecDB struct { // Default value is `Always` for `nightly` or `latest` images, and `IfNotPresent` in other cases. // +optional PostgresImagePullPolicy corev1.PullPolicy `json:"postgresImagePullPolicy,omitempty"` + // Postgres container custom settings + // +optional + ChePostgresContainerResources ResourcesCustomSettings `json:"chePostgresContainerResources,omitempty"` } // +k8s:openapi-gen=true @@ -437,6 +469,9 @@ type CheClusterSpecAuth struct { // Route custom settings // +optional IdentityProviderRoute RouteCustomSettings `json:"identityProviderRoute,omitempty"` + // Identity provider container custom settings + // +optional + IdentityProviderContainerResources ResourcesCustomSettings `json:"identityProviderContainerResources,omitempty"` } // Ingress custom settings, can be extended in the future @@ -453,6 +488,26 @@ type RouteCustomSettings struct { Labels string `json:"labels,omitempty"` } +// ResourceRequirements describes the compute resource requirements. +type ResourcesCustomSettings struct { + // Requests describes the minimum amount of compute resources required. + // +optional + Requests Resources `json:"request,omitempty"` + // Limits describes the maximum amount of compute resources allowed. + // +optional + Limits Resources `json:"limits,omitempty"` +} + +// List of resources +type Resources struct { + // Memory, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024) + // +optional + Memory string `json:"memory,omitempty"` + // CPU, in cores. (500m = .5 cores) + // +optional + Cpu string `json:"cpu,omitempty"` +} + // +k8s:openapi-gen=true // Configuration settings related to the persistent storage used by the Che installation. type CheClusterSpecStorage struct { diff --git a/pkg/apis/org/v1/zz_generated.deepcopy.go b/pkg/apis/org/v1/zz_generated.deepcopy.go index 67e520852..858172b00 100644 --- a/pkg/apis/org/v1/zz_generated.deepcopy.go +++ b/pkg/apis/org/v1/zz_generated.deepcopy.go @@ -103,6 +103,7 @@ func (in *CheClusterSpecAuth) DeepCopyInto(out *CheClusterSpecAuth) { } out.IdentityProviderIngress = in.IdentityProviderIngress out.IdentityProviderRoute = in.IdentityProviderRoute + out.IdentityProviderContainerResources = in.IdentityProviderContainerResources return } @@ -119,6 +120,7 @@ func (in *CheClusterSpecAuth) DeepCopy() *CheClusterSpecAuth { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CheClusterSpecDB) DeepCopyInto(out *CheClusterSpecDB) { *out = *in + out.ChePostgresContainerResources = in.ChePostgresContainerResources return } @@ -265,6 +267,40 @@ func (in *IngressCustomSettings) DeepCopy() *IngressCustomSettings { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Resources) DeepCopyInto(out *Resources) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Resources. +func (in *Resources) DeepCopy() *Resources { + if in == nil { + return nil + } + out := new(Resources) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourcesCustomSettings) DeepCopyInto(out *ResourcesCustomSettings) { + *out = *in + out.Requests = in.Requests + out.Limits = in.Limits + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcesCustomSettings. +func (in *ResourcesCustomSettings) DeepCopy() *ResourcesCustomSettings { + if in == nil { + return nil + } + out := new(ResourcesCustomSettings) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RouteCustomSettings) DeepCopyInto(out *RouteCustomSettings) { *out = *in diff --git a/pkg/controller/che/che_controller_test.go b/pkg/controller/che/che_controller_test.go index 8eb112255..387b17f4c 100644 --- a/pkg/controller/che/che_controller_test.go +++ b/pkg/controller/che/che_controller_test.go @@ -37,7 +37,6 @@ import ( operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" packagesv1 "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1" "github.com/sirupsen/logrus" - "gopkg.in/yaml.v2" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" rbacapi "k8s.io/api/rbac/v1" @@ -54,6 +53,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/reconcile" logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" + "sigs.k8s.io/yaml" "testing" ) diff --git a/pkg/deploy/defaults.go b/pkg/deploy/defaults.go index a2f4c9065..1c9f7215b 100644 --- a/pkg/deploy/defaults.go +++ b/pkg/deploy/defaults.go @@ -18,7 +18,7 @@ import ( "os" "strings" - "gopkg.in/yaml.v2" + "sigs.k8s.io/yaml" "github.com/eclipse/che-operator/pkg/util" "github.com/sirupsen/logrus" @@ -59,29 +59,21 @@ const ( DefaultPvcClaimSize = "1Gi" DefaultIngressClass = "nginx" - DefaultPluginRegistryMemoryLimit = "256Mi" - DefaultPluginRegistryMemoryRequest = "16Mi" - - // DefaultKube - DefaultDevfileRegistryMemoryLimit = "256Mi" - DefaultDevfileRegistryMemoryRequest = "16Mi" - DefaultKeycloakAdminUserName = "admin" - DefaultCheLogLevel = "INFO" - DefaultCheDebug = "false" - DefaultCheMultiUser = "true" - DefaultCheMetricsPort = int32(8087) - DefaultCheDebugPort = int32(8000) - DefaultCheVolumeMountPath = "/data" - DefaultCheVolumeClaimName = "che-data-volume" - DefaultPostgresVolumeClaimName = "postgres-data" + DefaultKeycloakAdminUserName = "admin" + DefaultCheLogLevel = "INFO" + DefaultCheDebug = "false" + DefaultCheMultiUser = "true" + DefaultCheMetricsPort = int32(8087) + DefaultCheDebugPort = int32(8000) + DefaultCheVolumeMountPath = "/data" + DefaultCheVolumeClaimName = "che-data-volume" + DefaultPostgresVolumeClaimName = "postgres-data" DefaultJavaOpts = "-XX:MaxRAMPercentage=85.0" DefaultWorkspaceJavaOpts = "-XX:MaxRAM=150m -XX:MaxRAMFraction=2 -XX:+UseParallelGC " + "-XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 " + "-Dsun.zip.disableMemoryMapping=true " + "-Xms20m -Djava.security.egd=file:/dev/./urandom" - DefaultServerMemoryRequest = "512Mi" - DefaultServerMemoryLimit = "1Gi" DefaultSecurityContextFsGroup = "1724" DefaultSecurityContextRunAsUser = "1724" @@ -113,6 +105,32 @@ const ( CheEclipseOrgMountAs = "che.eclipse.org/mount-as" CheEclipseOrgEnvName = "che.eclipse.org/env-name" CheEclipseOrgGithubOAuthCredentials = "che.eclipse.org/github-oauth-credentials" + + // limits + DefaultPluginRegistryMemoryLimit = "256Mi" + DefaultPluginRegistryMemoryRequest = "32Mi" + DefaultPluginRegistryCpuLimit = "500m" + DefaultPluginRegistryCpuRequest = "100m" + + DefaultDevfileRegistryMemoryLimit = "256Mi" + DefaultDevfileRegistryMemoryRequest = "32Mi" + DefaultDevfileRegistryCpuLimit = "500m" + DefaultDevfileRegistryCpuRequest = "100m" + + DefaultServerMemoryLimit = "1024Mi" + DefaultServerMemoryRequest = "512Mi" + DefaultServerCpuLimit = "1" + DefaultServerCpuRequest = "100m" + + DefaultIdentityProviderMemoryLimit = "1536Mi" + DefaultIdentityProviderMemoryRequest = "1024Mi" + DefaultIdentityProviderCpuLimit = "2" + DefaultIdentityProviderCpuRequest = "100m" + + DefaultPostgresMemoryLimit = "1024Mi" + DefaultPostgresMemoryRequest = "512Mi" + DefaultPostgresCpuLimit = "500m" + DefaultPostgresCpuRequest = "100m" ) func InitDefaults(defaultsPath string) { @@ -406,6 +424,8 @@ func InitTestDefaultsFromDeployment(deploymentFile string) error { } } + os.Setenv("MOCK_API", "true") + InitDefaultsFromEnv() return nil } diff --git a/pkg/deploy/devfile-registry/deployment.go b/pkg/deploy/devfile-registry/deployment.go index d55c753ca..7f40b4a1b 100644 --- a/pkg/deploy/devfile-registry/deployment.go +++ b/pkg/deploy/devfile-registry/deployment.go @@ -15,36 +15,61 @@ import ( "github.com/eclipse/che-operator/pkg/deploy" "github.com/eclipse/che-operator/pkg/deploy/registry" "github.com/eclipse/che-operator/pkg/util" + appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" ) func SyncDevfileRegistryDeploymentToCluster(deployContext *deploy.DeployContext) (bool, error) { - registryType := "devfile" - registryImage := util.GetValue(deployContext.CheCluster.Spec.Server.DevfileRegistryImage, deploy.DefaultDevfileRegistryImage(deployContext.CheCluster)) - registryImagePullPolicy := v1.PullPolicy(util.GetValue(string(deployContext.CheCluster.Spec.Server.PluginRegistryPullPolicy), deploy.DefaultPullPolicyFromDockerImage(registryImage))) - registryMemoryLimit := util.GetValue(string(deployContext.CheCluster.Spec.Server.DevfileRegistryMemoryLimit), deploy.DefaultDevfileRegistryMemoryLimit) - registryMemoryRequest := util.GetValue(string(deployContext.CheCluster.Spec.Server.DevfileRegistryMemoryRequest), deploy.DefaultDevfileRegistryMemoryRequest) - probePath := "/devfiles/" - devfileImagesEnv := util.GetEnvByRegExp("^.*devfile_registry_image.*$") - clusterDeployment, err := deploy.GetClusterDeployment(deploy.DevfileRegistry, deployContext.CheCluster.Namespace, deployContext.ClusterAPI.Client) if err != nil { return false, err } + specDeployment, err := GetDevfileRegistrySpecDeployment(deployContext) + if err != nil { + return false, err + } + + return deploy.SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, nil, nil) +} + +func GetDevfileRegistrySpecDeployment(deployContext *deploy.DeployContext) (*appsv1.Deployment, error) { + registryType := "devfile" + registryImage := util.GetValue(deployContext.CheCluster.Spec.Server.DevfileRegistryImage, deploy.DefaultDevfileRegistryImage(deployContext.CheCluster)) + registryImagePullPolicy := v1.PullPolicy(util.GetValue(string(deployContext.CheCluster.Spec.Server.DevfileRegistryPullPolicy), deploy.DefaultPullPolicyFromDockerImage(registryImage))) + probePath := "/devfiles/" + devfileImagesEnv := util.GetEnvByRegExp("^.*devfile_registry_image.*$") + + resources := v1.ResourceRequirements{ + Requests: v1.ResourceList{ + v1.ResourceMemory: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Server.DevfileRegistryMemoryRequest, + deploy.DefaultDevfileRegistryMemoryRequest), + v1.ResourceCPU: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Server.DevfileRegistryCpuRequest, + deploy.DefaultDevfileRegistryCpuRequest), + }, + Limits: v1.ResourceList{ + v1.ResourceMemory: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Server.DevfileRegistryMemoryLimit, + deploy.DefaultDevfileRegistryMemoryLimit), + v1.ResourceCPU: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Server.DevfileRegistryCpuLimit, + deploy.DefaultDevfileRegistryCpuLimit), + }, + } + specDeployment, err := registry.GetSpecRegistryDeployment( deployContext, registryType, registryImage, devfileImagesEnv, registryImagePullPolicy, - registryMemoryLimit, - registryMemoryRequest, + resources, probePath) - if err != nil { - return false, err + return nil, err } - return deploy.SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, nil, nil) + return specDeployment, nil } diff --git a/pkg/deploy/devfile-registry/deployment_test.go b/pkg/deploy/devfile-registry/deployment_test.go new file mode 100644 index 000000000..5226c8e6d --- /dev/null +++ b/pkg/deploy/devfile-registry/deployment_test.go @@ -0,0 +1,113 @@ +// +// Copyright (c) 2012-2019 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 devfile_registry + +import ( + "os" + + "github.com/eclipse/che-operator/pkg/util" + + "github.com/eclipse/che-operator/pkg/deploy" + + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" + + "testing" +) + +func TestDeployment(t *testing.T) { + type testCase struct { + name string + initObjects []runtime.Object + memoryLimit string + memoryRequest string + cpuRequest string + cpuLimit string + cheCluster *orgv1.CheCluster + } + + testCases := []testCase{ + { + name: "Test default limits", + initObjects: []runtime.Object{}, + memoryLimit: deploy.DefaultDevfileRegistryMemoryLimit, + memoryRequest: deploy.DefaultDevfileRegistryMemoryRequest, + cpuLimit: deploy.DefaultDevfileRegistryCpuLimit, + cpuRequest: deploy.DefaultDevfileRegistryCpuRequest, + cheCluster: &orgv1.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + }, + }, + }, + { + name: "Test custom limits", + initObjects: []runtime.Object{}, + cpuLimit: "250m", + cpuRequest: "150m", + memoryLimit: "250Mi", + memoryRequest: "150Mi", + cheCluster: &orgv1.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + }, + Spec: orgv1.CheClusterSpec{ + Server: orgv1.CheClusterSpecServer{ + DevfileRegistryCpuLimit: "250m", + DevfileRegistryCpuRequest: "150m", + DevfileRegistryMemoryLimit: "250Mi", + DevfileRegistryMemoryRequest: "150Mi", + }, + }, + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + logf.SetLogger(zap.LoggerTo(os.Stdout, true)) + orgv1.SchemeBuilder.AddToScheme(scheme.Scheme) + testCase.initObjects = append(testCase.initObjects) + cli := fake.NewFakeClientWithScheme(scheme.Scheme, testCase.initObjects...) + + deployContext := &deploy.DeployContext{ + ClusterAPI: deploy.ClusterAPI{ + Client: cli, + Scheme: scheme.Scheme, + }, + Proxy: &deploy.Proxy{}, + CheCluster: testCase.cheCluster, + } + + deployment, err := GetDevfileRegistrySpecDeployment(deployContext) + if err != nil { + t.Fatalf("Error creating deployment: %v", err) + } + + util.CompareResources(deployment, + util.TestExpectedResources{ + MemoryLimit: testCase.memoryLimit, + MemoryRequest: testCase.memoryRequest, + CpuRequest: testCase.cpuRequest, + CpuLimit: testCase.cpuLimit, + }, + t) + + util.ValidateSecurityContext(deployment, t) + }) + } +} diff --git a/pkg/deploy/devfile-registry/init_test.go b/pkg/deploy/devfile-registry/init_test.go new file mode 100644 index 000000000..f8e650565 --- /dev/null +++ b/pkg/deploy/devfile-registry/init_test.go @@ -0,0 +1,21 @@ +// +// Copyright (c) 2020-2020 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 devfile_registry + +import "github.com/eclipse/che-operator/pkg/deploy" + +func init() { + err := deploy.InitTestDefaultsFromDeployment("../../../deploy/operator.yaml") + if err != nil { + panic(err) + } +} diff --git a/pkg/deploy/identity-provider/deployment_keycloak.go b/pkg/deploy/identity-provider/deployment_keycloak.go index bac2a27bd..57835b0e9 100644 --- a/pkg/deploy/identity-provider/deployment_keycloak.go +++ b/pkg/deploy/identity-provider/deployment_keycloak.go @@ -27,7 +27,6 @@ import ( appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" @@ -64,7 +63,7 @@ func SyncKeycloakDeploymentToCluster(deployContext *deploy.DeployContext) (bool, return false, err } - specDeployment, err := getSpecKeycloakDeployment(deployContext, clusterDeployment) + specDeployment, err := GetSpecKeycloakDeployment(deployContext, clusterDeployment) if err != nil { return false, err } @@ -72,7 +71,7 @@ func SyncKeycloakDeploymentToCluster(deployContext *deploy.DeployContext) (bool, return deploy.SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, keycloakCustomDiffOpts, keycloakAdditionalDeploymentMerge) } -func getSpecKeycloakDeployment( +func GetSpecKeycloakDeployment( deployContext *deploy.DeployContext, clusterDeployment *appsv1.Deployment) (*appsv1.Deployment, error) { optionalEnv := true @@ -588,10 +587,20 @@ func getSpecKeycloakDeployment( }, Resources: corev1.ResourceRequirements{ Requests: corev1.ResourceList{ - corev1.ResourceMemory: resource.MustParse("512Mi"), + corev1.ResourceMemory: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Auth.IdentityProviderContainerResources.Requests.Memory, + deploy.DefaultIdentityProviderMemoryRequest), + corev1.ResourceCPU: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Auth.IdentityProviderContainerResources.Requests.Cpu, + deploy.DefaultIdentityProviderCpuRequest), }, Limits: corev1.ResourceList{ - corev1.ResourceMemory: resource.MustParse("2Gi"), + corev1.ResourceMemory: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Auth.IdentityProviderContainerResources.Limits.Memory, + deploy.DefaultIdentityProviderMemoryLimit), + corev1.ResourceCPU: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Auth.IdentityProviderContainerResources.Limits.Cpu, + deploy.DefaultIdentityProviderCpuLimit), }, }, ReadinessProbe: &corev1.Probe{ @@ -605,7 +614,7 @@ func getSpecKeycloakDeployment( Scheme: corev1.URISchemeHTTP, }, }, - InitialDelaySeconds: 25, + InitialDelaySeconds: 30, FailureThreshold: 10, TimeoutSeconds: 5, PeriodSeconds: 10, @@ -617,7 +626,7 @@ func getSpecKeycloakDeployment( Port: intstr.FromInt(8080), }, }, - InitialDelaySeconds: 30, + InitialDelaySeconds: 90, FailureThreshold: 10, TimeoutSeconds: 5, PeriodSeconds: 10, diff --git a/pkg/deploy/identity-provider/deployment_keycloak_test.go b/pkg/deploy/identity-provider/deployment_keycloak_test.go new file mode 100644 index 000000000..6d5b5495c --- /dev/null +++ b/pkg/deploy/identity-provider/deployment_keycloak_test.go @@ -0,0 +1,119 @@ +// +// Copyright (c) 2012-2019 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 identity_provider + +import ( + "os" + + "github.com/eclipse/che-operator/pkg/util" + + "github.com/eclipse/che-operator/pkg/deploy" + + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" + + "testing" +) + +func TestDeployment(t *testing.T) { + type testCase struct { + name string + initObjects []runtime.Object + memoryLimit string + memoryRequest string + cpuLimit string + cpuRequest string + cheCluster *orgv1.CheCluster + } + + testCases := []testCase{ + { + name: "Test default limits", + initObjects: []runtime.Object{}, + memoryLimit: deploy.DefaultIdentityProviderMemoryLimit, + memoryRequest: deploy.DefaultIdentityProviderMemoryRequest, + cpuLimit: deploy.DefaultIdentityProviderCpuLimit, + cpuRequest: deploy.DefaultIdentityProviderCpuRequest, + cheCluster: &orgv1.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + }, + }, + }, + { + name: "Test custom limits", + initObjects: []runtime.Object{}, + cpuLimit: "250m", + cpuRequest: "150m", + memoryLimit: "250Mi", + memoryRequest: "150Mi", + cheCluster: &orgv1.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + }, + Spec: orgv1.CheClusterSpec{ + Auth: orgv1.CheClusterSpecAuth{ + IdentityProviderContainerResources: orgv1.ResourcesCustomSettings{ + Limits: orgv1.Resources{ + Cpu: "250m", + Memory: "250Mi", + }, + Requests: orgv1.Resources{ + Cpu: "150m", + Memory: "150Mi", + }, + }, + }, + }, + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + logf.SetLogger(zap.LoggerTo(os.Stdout, true)) + orgv1.SchemeBuilder.AddToScheme(scheme.Scheme) + testCase.initObjects = append(testCase.initObjects) + cli := fake.NewFakeClientWithScheme(scheme.Scheme, testCase.initObjects...) + + deployContext := &deploy.DeployContext{ + CheCluster: testCase.cheCluster, + ClusterAPI: deploy.ClusterAPI{ + Client: cli, + Scheme: scheme.Scheme, + }, + Proxy: &deploy.Proxy{}, + } + + deployment, err := GetSpecKeycloakDeployment(deployContext, nil) + if err != nil { + t.Fatalf("Error creating deployment: %v", err) + } + + util.CompareResources(deployment, + util.TestExpectedResources{ + MemoryLimit: testCase.memoryLimit, + MemoryRequest: testCase.memoryRequest, + CpuRequest: testCase.cpuRequest, + CpuLimit: testCase.cpuLimit, + }, + t) + + util.ValidateSecurityContext(deployment, t) + }) + } +} diff --git a/pkg/deploy/identity-provider/init_test.go b/pkg/deploy/identity-provider/init_test.go new file mode 100644 index 000000000..b82b045c9 --- /dev/null +++ b/pkg/deploy/identity-provider/init_test.go @@ -0,0 +1,21 @@ +// +// Copyright (c) 2020-2020 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 identity_provider + +import "github.com/eclipse/che-operator/pkg/deploy" + +func init() { + err := deploy.InitTestDefaultsFromDeployment("../../../deploy/operator.yaml") + if err != nil { + panic(err) + } +} diff --git a/pkg/deploy/plugin-registry/deployment.go b/pkg/deploy/plugin-registry/deployment.go index 8d6dfa9a3..6b61d9168 100644 --- a/pkg/deploy/plugin-registry/deployment.go +++ b/pkg/deploy/plugin-registry/deployment.go @@ -15,36 +15,61 @@ import ( "github.com/eclipse/che-operator/pkg/deploy" "github.com/eclipse/che-operator/pkg/deploy/registry" "github.com/eclipse/che-operator/pkg/util" + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" ) func SyncPluginRegistryDeploymentToCluster(deployContext *deploy.DeployContext) (bool, error) { - registryType := "plugin" - registryImage := util.GetValue(deployContext.CheCluster.Spec.Server.PluginRegistryImage, deploy.DefaultPluginRegistryImage(deployContext.CheCluster)) - registryImagePullPolicy := corev1.PullPolicy(util.GetValue(string(deployContext.CheCluster.Spec.Server.PluginRegistryPullPolicy), deploy.DefaultPullPolicyFromDockerImage(registryImage))) - registryMemoryLimit := util.GetValue(string(deployContext.CheCluster.Spec.Server.PluginRegistryMemoryLimit), deploy.DefaultPluginRegistryMemoryLimit) - registryMemoryRequest := util.GetValue(string(deployContext.CheCluster.Spec.Server.PluginRegistryMemoryRequest), deploy.DefaultPluginRegistryMemoryRequest) - probePath := "/v3/plugins/" - pluginImagesEnv := util.GetEnvByRegExp("^.*plugin_registry_image.*$") - clusterDeployment, err := deploy.GetClusterDeployment(deploy.PluginRegistry, deployContext.CheCluster.Namespace, deployContext.ClusterAPI.Client) if err != nil { return false, err } + specDeployment, err := GetPluginRegistrySpecDeployment(deployContext) + if err != nil { + return false, err + } + + return deploy.SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, nil, nil) +} + +func GetPluginRegistrySpecDeployment(deployContext *deploy.DeployContext) (*appsv1.Deployment, error) { + registryType := "plugin" + registryImage := util.GetValue(deployContext.CheCluster.Spec.Server.PluginRegistryImage, deploy.DefaultPluginRegistryImage(deployContext.CheCluster)) + registryImagePullPolicy := corev1.PullPolicy(util.GetValue(string(deployContext.CheCluster.Spec.Server.PluginRegistryPullPolicy), deploy.DefaultPullPolicyFromDockerImage(registryImage))) + probePath := "/v3/plugins/" + pluginImagesEnv := util.GetEnvByRegExp("^.*plugin_registry_image.*$") + + resources := corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceMemory: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Server.PluginRegistryMemoryRequest, + deploy.DefaultPluginRegistryMemoryRequest), + corev1.ResourceCPU: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Server.PluginRegistryCpuRequest, + deploy.DefaultPluginRegistryCpuRequest), + }, + Limits: corev1.ResourceList{ + corev1.ResourceMemory: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Server.PluginRegistryMemoryLimit, + deploy.DefaultPluginRegistryMemoryLimit), + corev1.ResourceCPU: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Server.PluginRegistryCpuLimit, + deploy.DefaultPluginRegistryCpuLimit), + }, + } + specDeployment, err := registry.GetSpecRegistryDeployment( deployContext, registryType, registryImage, pluginImagesEnv, registryImagePullPolicy, - registryMemoryLimit, - registryMemoryRequest, + resources, probePath) - if err != nil { - return false, err + return nil, err } - return deploy.SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, nil, nil) + return specDeployment, nil } diff --git a/pkg/deploy/plugin-registry/deployment_test.go b/pkg/deploy/plugin-registry/deployment_test.go new file mode 100644 index 000000000..d6ca85725 --- /dev/null +++ b/pkg/deploy/plugin-registry/deployment_test.go @@ -0,0 +1,113 @@ +// +// Copyright (c) 2012-2019 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 plugin_registry + +import ( + "os" + + "github.com/eclipse/che-operator/pkg/util" + + "github.com/eclipse/che-operator/pkg/deploy" + + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" + + "testing" +) + +func TestDeployment(t *testing.T) { + type testCase struct { + name string + initObjects []runtime.Object + memoryLimit string + memoryRequest string + cpuRequest string + cpuLimit string + cheCluster *orgv1.CheCluster + } + + testCases := []testCase{ + { + name: "Test default limits", + initObjects: []runtime.Object{}, + memoryLimit: deploy.DefaultPluginRegistryMemoryLimit, + memoryRequest: deploy.DefaultPluginRegistryMemoryRequest, + cpuLimit: deploy.DefaultPluginRegistryCpuLimit, + cpuRequest: deploy.DefaultPluginRegistryCpuRequest, + cheCluster: &orgv1.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + }, + }, + }, + { + name: "Test custom limits", + initObjects: []runtime.Object{}, + cpuLimit: "250m", + cpuRequest: "150m", + memoryLimit: "250Mi", + memoryRequest: "150Mi", + cheCluster: &orgv1.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + }, + Spec: orgv1.CheClusterSpec{ + Server: orgv1.CheClusterSpecServer{ + PluginRegistryCpuLimit: "250m", + PluginRegistryCpuRequest: "150m", + PluginRegistryMemoryLimit: "250Mi", + PluginRegistryMemoryRequest: "150Mi", + }, + }, + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + logf.SetLogger(zap.LoggerTo(os.Stdout, true)) + orgv1.SchemeBuilder.AddToScheme(scheme.Scheme) + testCase.initObjects = append(testCase.initObjects) + cli := fake.NewFakeClientWithScheme(scheme.Scheme, testCase.initObjects...) + + deployContext := &deploy.DeployContext{ + CheCluster: testCase.cheCluster, + ClusterAPI: deploy.ClusterAPI{ + Client: cli, + Scheme: scheme.Scheme, + }, + Proxy: &deploy.Proxy{}, + } + + deployment, err := GetPluginRegistrySpecDeployment(deployContext) + if err != nil { + t.Fatalf("Error creating deployment: %v", err) + } + + util.CompareResources(deployment, + util.TestExpectedResources{ + MemoryLimit: testCase.memoryLimit, + MemoryRequest: testCase.memoryRequest, + CpuRequest: testCase.cpuRequest, + CpuLimit: testCase.cpuLimit, + }, + t) + + util.ValidateSecurityContext(deployment, t) + }) + } +} diff --git a/pkg/deploy/plugin-registry/init_test.go b/pkg/deploy/plugin-registry/init_test.go new file mode 100644 index 000000000..b64da828c --- /dev/null +++ b/pkg/deploy/plugin-registry/init_test.go @@ -0,0 +1,21 @@ +// +// Copyright (c) 2020-2020 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 plugin_registry + +import "github.com/eclipse/che-operator/pkg/deploy" + +func init() { + err := deploy.InitTestDefaultsFromDeployment("../../../deploy/operator.yaml") + if err != nil { + panic(err) + } +} diff --git a/pkg/deploy/postgres/deployment_posgres_test.go b/pkg/deploy/postgres/deployment_posgres_test.go new file mode 100644 index 000000000..614c07d38 --- /dev/null +++ b/pkg/deploy/postgres/deployment_posgres_test.go @@ -0,0 +1,119 @@ +// +// Copyright (c) 2012-2019 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 postgres + +import ( + "os" + + "github.com/eclipse/che-operator/pkg/util" + + "github.com/eclipse/che-operator/pkg/deploy" + + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" + + "testing" +) + +func TestDeployment(t *testing.T) { + type testCase struct { + name string + initObjects []runtime.Object + memoryLimit string + memoryRequest string + cpuLimit string + cpuRequest string + cheCluster *orgv1.CheCluster + } + + testCases := []testCase{ + { + name: "Test default limits", + initObjects: []runtime.Object{}, + memoryLimit: deploy.DefaultPostgresMemoryLimit, + memoryRequest: deploy.DefaultPostgresMemoryRequest, + cpuLimit: deploy.DefaultPostgresCpuLimit, + cpuRequest: deploy.DefaultPostgresCpuRequest, + cheCluster: &orgv1.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + }, + }, + }, + { + name: "Test custom limits", + initObjects: []runtime.Object{}, + cpuLimit: "250m", + cpuRequest: "150m", + memoryLimit: "250Mi", + memoryRequest: "150Mi", + cheCluster: &orgv1.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + }, + Spec: orgv1.CheClusterSpec{ + Database: orgv1.CheClusterSpecDB{ + ChePostgresContainerResources: orgv1.ResourcesCustomSettings{ + Limits: orgv1.Resources{ + Cpu: "250m", + Memory: "250Mi", + }, + Requests: orgv1.Resources{ + Memory: "150Mi", + Cpu: "150m", + }, + }, + }, + }, + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + logf.SetLogger(zap.LoggerTo(os.Stdout, true)) + orgv1.SchemeBuilder.AddToScheme(scheme.Scheme) + testCase.initObjects = append(testCase.initObjects) + cli := fake.NewFakeClientWithScheme(scheme.Scheme, testCase.initObjects...) + + deployContext := &deploy.DeployContext{ + CheCluster: testCase.cheCluster, + ClusterAPI: deploy.ClusterAPI{ + Client: cli, + Scheme: scheme.Scheme, + }, + Proxy: &deploy.Proxy{}, + } + + deployment, err := GetSpecPostgresDeployment(deployContext, nil) + if err != nil { + t.Fatalf("Error creating deployment: %v", err) + } + + util.CompareResources(deployment, + util.TestExpectedResources{ + MemoryLimit: testCase.memoryLimit, + MemoryRequest: testCase.memoryRequest, + CpuRequest: testCase.cpuRequest, + CpuLimit: testCase.cpuLimit, + }, + t) + + util.ValidateSecurityContext(deployment, t) + }) + } +} diff --git a/pkg/deploy/postgres/deployment_postgres.go b/pkg/deploy/postgres/deployment_postgres.go index b6bd92309..a093ae1d7 100644 --- a/pkg/deploy/postgres/deployment_postgres.go +++ b/pkg/deploy/postgres/deployment_postgres.go @@ -16,7 +16,6 @@ import ( "github.com/eclipse/che-operator/pkg/util" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -36,7 +35,7 @@ func SyncPostgresDeploymentToCluster(deployContext *deploy.DeployContext) (bool, return false, err } - specDeployment, err := getSpecPostgresDeployment(deployContext, clusterDeployment) + specDeployment, err := GetSpecPostgresDeployment(deployContext, clusterDeployment) if err != nil { return false, err } @@ -44,7 +43,7 @@ func SyncPostgresDeploymentToCluster(deployContext *deploy.DeployContext) (bool, return deploy.SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, nil, nil) } -func getSpecPostgresDeployment(deployContext *deploy.DeployContext, clusterDeployment *appsv1.Deployment) (*appsv1.Deployment, error) { +func GetSpecPostgresDeployment(deployContext *deploy.DeployContext, clusterDeployment *appsv1.Deployment) (*appsv1.Deployment, error) { isOpenShift, _, err := util.DetectOpenShift() if err != nil { return nil, err @@ -110,10 +109,20 @@ func getSpecPostgresDeployment(deployContext *deploy.DeployContext, clusterDeplo }, Resources: corev1.ResourceRequirements{ Requests: corev1.ResourceList{ - corev1.ResourceMemory: resource.MustParse("512Mi"), + corev1.ResourceMemory: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Database.ChePostgresContainerResources.Requests.Memory, + deploy.DefaultPostgresMemoryRequest), + corev1.ResourceCPU: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Database.ChePostgresContainerResources.Requests.Cpu, + deploy.DefaultPostgresCpuRequest), }, Limits: corev1.ResourceList{ - corev1.ResourceMemory: resource.MustParse("1Gi"), + corev1.ResourceMemory: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Database.ChePostgresContainerResources.Limits.Memory, + deploy.DefaultPostgresMemoryLimit), + corev1.ResourceCPU: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Database.ChePostgresContainerResources.Limits.Cpu, + deploy.DefaultPostgresCpuLimit), }, }, VolumeMounts: []corev1.VolumeMount{ diff --git a/pkg/deploy/postgres/init_test.go b/pkg/deploy/postgres/init_test.go new file mode 100644 index 000000000..5d2e23972 --- /dev/null +++ b/pkg/deploy/postgres/init_test.go @@ -0,0 +1,21 @@ +// +// Copyright (c) 2020-2020 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 postgres + +import "github.com/eclipse/che-operator/pkg/deploy" + +func init() { + err := deploy.InitTestDefaultsFromDeployment("../../../deploy/operator.yaml") + if err != nil { + panic(err) + } +} diff --git a/pkg/deploy/registry/registry.go b/pkg/deploy/registry/registry.go index 33b58d271..014ce3cf0 100644 --- a/pkg/deploy/registry/registry.go +++ b/pkg/deploy/registry/registry.go @@ -5,7 +5,6 @@ import ( "github.com/eclipse/che-operator/pkg/util" v12 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" v13 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -17,8 +16,7 @@ func GetSpecRegistryDeployment( registryImage string, env []v1.EnvVar, registryImagePullPolicy v1.PullPolicy, - registryMemoryLimit string, - registryMemoryRequest string, + resources v1.ResourceRequirements, probePath string) (*v12.Deployment, error) { terminationGracePeriodSeconds := int64(30) @@ -77,14 +75,7 @@ func GetSpecRegistryDeployment( }, }, }, - Resources: v1.ResourceRequirements{ - Requests: v1.ResourceList{ - v1.ResourceMemory: resource.MustParse(registryMemoryRequest), - }, - Limits: v1.ResourceList{ - v1.ResourceMemory: resource.MustParse(registryMemoryLimit), - }, - }, + Resources: resources, ReadinessProbe: &v1.Probe{ Handler: v1.Handler{ HTTPGet: &v1.HTTPGetAction{ diff --git a/pkg/deploy/server/deployment_che.go b/pkg/deploy/server/deployment_che.go index 489eaed77..fa974fa7b 100644 --- a/pkg/deploy/server/deployment_che.go +++ b/pkg/deploy/server/deployment_che.go @@ -21,7 +21,6 @@ import ( "github.com/eclipse/che-operator/pkg/util" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -33,7 +32,7 @@ func SyncCheDeploymentToCluster(deployContext *deploy.DeployContext) (bool, erro return false, err } - specDeployment, err := getSpecCheDeployment(deployContext) + specDeployment, err := GetSpecCheDeployment(deployContext) if err != nil { return false, err } @@ -41,7 +40,7 @@ func SyncCheDeploymentToCluster(deployContext *deploy.DeployContext) (bool, erro return deploy.SyncDeploymentToCluster(deployContext, specDeployment, clusterDeployment, nil, nil) } -func getSpecCheDeployment(deployContext *deploy.DeployContext) (*appsv1.Deployment, error) { +func GetSpecCheDeployment(deployContext *deploy.DeployContext) (*appsv1.Deployment, error) { isOpenShift, _, err := util.DetectOpenShift() if err != nil { return nil, err @@ -59,7 +58,6 @@ func getSpecCheDeployment(deployContext *deploy.DeployContext) (*appsv1.Deployme cheFlavor := deploy.DefaultCheFlavor(deployContext.CheCluster) labels := deploy.GetLabels(deployContext.CheCluster, cheFlavor) optionalEnv := true - memRequest := util.GetValue(deployContext.CheCluster.Spec.Server.ServerMemoryRequest, deploy.DefaultServerMemoryRequest) selfSignedCertEnv := corev1.EnvVar{ Name: "CHE_SELF__SIGNED__CERT", Value: "", @@ -182,7 +180,6 @@ func getSpecCheDeployment(deployContext *deploy.DeployContext) (*appsv1.Deployme FieldPath: "metadata.namespace"}}, }) - memLimit := util.GetValue(deployContext.CheCluster.Spec.Server.ServerMemoryLimit, deploy.DefaultServerMemoryLimit) cheImageAndTag := GetFullCheServerImageLink(deployContext.CheCluster) pullPolicy := corev1.PullPolicy(util.GetValue(string(deployContext.CheCluster.Spec.Server.CheImagePullPolicy), deploy.DefaultPullPolicyFromDockerImage(cheImageAndTag))) @@ -235,10 +232,20 @@ func getSpecCheDeployment(deployContext *deploy.DeployContext) (*appsv1.Deployme }, Resources: corev1.ResourceRequirements{ Requests: corev1.ResourceList{ - corev1.ResourceMemory: resource.MustParse(memRequest), + corev1.ResourceMemory: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Server.ServerMemoryRequest, + deploy.DefaultServerMemoryRequest), + corev1.ResourceCPU: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Server.ServerCpuRequest, + deploy.DefaultServerCpuRequest), }, Limits: corev1.ResourceList{ - corev1.ResourceMemory: resource.MustParse(memLimit), + corev1.ResourceMemory: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Server.ServerMemoryLimit, + deploy.DefaultServerMemoryLimit), + corev1.ResourceCPU: util.GetResourceQuantity( + deployContext.CheCluster.Spec.Server.ServerCpuLimit, + deploy.DefaultServerCpuLimit), }, }, SecurityContext: &corev1.SecurityContext{ diff --git a/pkg/deploy/server/deployment_che_test.go b/pkg/deploy/server/deployment_che_test.go new file mode 100644 index 000000000..d1840ea2a --- /dev/null +++ b/pkg/deploy/server/deployment_che_test.go @@ -0,0 +1,112 @@ +// +// Copyright (c) 2012-2019 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 server + +import ( + "os" + + "github.com/eclipse/che-operator/pkg/util" + + "github.com/eclipse/che-operator/pkg/deploy" + + orgv1 "github.com/eclipse/che-operator/pkg/apis/org/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" + + "testing" +) + +func TestDeployment(t *testing.T) { + type testCase struct { + name string + initObjects []runtime.Object + memoryLimit string + memoryRequest string + cpuLimit string + cpuRequest string + cheCluster *orgv1.CheCluster + } + + testCases := []testCase{ + { + name: "Test default limits", + initObjects: []runtime.Object{}, + memoryLimit: deploy.DefaultServerMemoryLimit, + memoryRequest: deploy.DefaultServerMemoryRequest, + cpuLimit: deploy.DefaultServerCpuLimit, + cpuRequest: deploy.DefaultServerCpuRequest, + cheCluster: &orgv1.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + }, + }, + }, + { + name: "Test custom limits", + initObjects: []runtime.Object{}, + cpuLimit: "250m", + cpuRequest: "150m", + memoryLimit: "250Mi", + memoryRequest: "150Mi", + cheCluster: &orgv1.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + }, + Spec: orgv1.CheClusterSpec{ + Server: orgv1.CheClusterSpecServer{ + ServerCpuLimit: "250m", + ServerCpuRequest: "150m", + ServerMemoryLimit: "250Mi", + ServerMemoryRequest: "150Mi", + }, + }, + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + logf.SetLogger(zap.LoggerTo(os.Stdout, true)) + orgv1.SchemeBuilder.AddToScheme(scheme.Scheme) + testCase.initObjects = append(testCase.initObjects) + cli := fake.NewFakeClientWithScheme(scheme.Scheme, testCase.initObjects...) + + deployContext := &deploy.DeployContext{ + CheCluster: testCase.cheCluster, + ClusterAPI: deploy.ClusterAPI{ + Client: cli, + Scheme: scheme.Scheme, + }, + } + + deployment, err := GetSpecCheDeployment(deployContext) + if err != nil { + t.Fatalf("Error creating deployment: %v", err) + } + + util.CompareResources(deployment, + util.TestExpectedResources{ + MemoryLimit: testCase.memoryLimit, + MemoryRequest: testCase.memoryRequest, + CpuRequest: testCase.cpuRequest, + CpuLimit: testCase.cpuLimit, + }, + t) + + util.ValidateSecurityContext(deployment, t) + }) + } +} diff --git a/pkg/util/test_util.go b/pkg/util/test_util.go new file mode 100644 index 000000000..31e485c9b --- /dev/null +++ b/pkg/util/test_util.go @@ -0,0 +1,69 @@ +// +// Copyright (c) 2012-2019 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 util + +import ( + "testing" + + appsv1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/resource" +) + +type TestExpectedResources struct { + MemoryLimit string + MemoryRequest string + CpuRequest string + CpuLimit string +} + +func CompareResources(actualDeployment *appsv1.Deployment, expected TestExpectedResources, t *testing.T) { + compareQuantity( + "Memory limits", + actualDeployment.Spec.Template.Spec.Containers[0].Resources.Limits.Memory(), + expected.MemoryLimit, + t, + ) + + compareQuantity( + "Memory requests", + actualDeployment.Spec.Template.Spec.Containers[0].Resources.Requests.Memory(), + expected.MemoryRequest, + t, + ) + + compareQuantity( + "CPU limits", + actualDeployment.Spec.Template.Spec.Containers[0].Resources.Limits.Cpu(), + expected.CpuLimit, + t, + ) + + compareQuantity( + "CPU requests", + actualDeployment.Spec.Template.Spec.Containers[0].Resources.Requests.Cpu(), + expected.CpuRequest, + t, + ) +} + +func ValidateSecurityContext(actualDeployment *appsv1.Deployment, t *testing.T) { + if actualDeployment.Spec.Template.Spec.Containers[0].SecurityContext.Capabilities.Drop[0] != "ALL" { + t.Error("Deployment doesn't contain 'Capabilities Drop ALL' in a SecurityContext") + } +} + +func compareQuantity(resource string, actualQuantity *resource.Quantity, expected string, t *testing.T) { + expectedQuantity := GetResourceQuantity(expected, expected) + if !actualQuantity.Equal(expectedQuantity) { + t.Errorf("%s: expected %s, actual %s", resource, expectedQuantity.String(), actualQuantity.String()) + } +} diff --git a/pkg/util/util.go b/pkg/util/util.go index 9b6072f31..5ad55a2d4 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -32,6 +32,7 @@ import ( "github.com/sirupsen/logrus" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/discovery" "sigs.k8s.io/controller-runtime/pkg/client/config" @@ -353,3 +354,10 @@ func IsOAuthEnabled(c *orgv1.CheCluster) bool { } return false } + +func GetResourceQuantity(value string, defaultValue string) resource.Quantity { + if value != "" { + return resource.MustParse(value) + } + return resource.MustParse(defaultValue) +}