From f5e122e8ef734d89b9d9f67fc03b0c6446312f5f Mon Sep 17 00:00:00 2001
From: Motte <37443982+dmotte@users.noreply.github.com>
Date: Wed, 16 Oct 2024 17:19:07 +0200
Subject: [PATCH] Fix resource constraints (#2735)

* Add empty string cases to patterns for pod resources
* Added empty strings test case
* Restored k8sres.go and changed test to zeros
* Updated validation pattern in manifests/operatorconfiguration.crd.yaml and pkg/apis/acid.zalan.do/v1/crds.go
---
 .../crds/operatorconfigurations.yaml          | 16 ++++----
 manifests/operatorconfiguration.crd.yaml      | 16 ++++----
 pkg/apis/acid.zalan.do/v1/crds.go             | 16 ++++----
 pkg/cluster/k8sres_test.go                    | 38 +++++++++++++++++++
 4 files changed, 62 insertions(+), 24 deletions(-)

diff --git a/charts/postgres-operator/crds/operatorconfigurations.yaml b/charts/postgres-operator/crds/operatorconfigurations.yaml
index 5edb7044..0a1e7461 100644
--- a/charts/postgres-operator/crds/operatorconfigurations.yaml
+++ b/charts/postgres-operator/crds/operatorconfigurations.yaml
@@ -376,28 +376,28 @@ spec:
                 properties:
                   default_cpu_limit:
                     type: string
-                    pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
+                    pattern: '^(\d+m|\d+(\.\d{1,3})?)$|^$'
                   default_cpu_request:
                     type: string
-                    pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
+                    pattern: '^(\d+m|\d+(\.\d{1,3})?)$|^$'
                   default_memory_limit:
                     type: string
-                    pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
+                    pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$|^$'
                   default_memory_request:
                     type: string
-                    pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
+                    pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$|^$'
                   max_cpu_request:
                     type: string
-                    pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
+                    pattern: '^(\d+m|\d+(\.\d{1,3})?)$|^$'
                   max_memory_request:
                     type: string
-                    pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
+                    pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$|^$'
                   min_cpu_limit:
                     type: string
-                    pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
+                    pattern: '^(\d+m|\d+(\.\d{1,3})?)$|^$'
                   min_memory_limit:
                     type: string
-                    pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
+                    pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$|^$'
               timeouts:
                 type: object
                 properties:
diff --git a/manifests/operatorconfiguration.crd.yaml b/manifests/operatorconfiguration.crd.yaml
index c2b0cf39..a7b1a728 100644
--- a/manifests/operatorconfiguration.crd.yaml
+++ b/manifests/operatorconfiguration.crd.yaml
@@ -374,28 +374,28 @@ spec:
                 properties:
                   default_cpu_limit:
                     type: string
-                    pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
+                    pattern: '^(\d+m|\d+(\.\d{1,3})?)$|^$'
                   default_cpu_request:
                     type: string
-                    pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
+                    pattern: '^(\d+m|\d+(\.\d{1,3})?)$|^$'
                   default_memory_limit:
                     type: string
-                    pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
+                    pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$|^$'
                   default_memory_request:
                     type: string
-                    pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
+                    pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$|^$'
                   max_cpu_request:
                     type: string
-                    pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
+                    pattern: '^(\d+m|\d+(\.\d{1,3})?)$|^$'
                   max_memory_request:
                     type: string
-                    pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
+                    pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$|^$'
                   min_cpu_limit:
                     type: string
-                    pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
+                    pattern: '^(\d+m|\d+(\.\d{1,3})?)$|^$'
                   min_memory_limit:
                     type: string
-                    pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
+                    pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$|^$'
               timeouts:
                 type: object
                 properties:
diff --git a/pkg/apis/acid.zalan.do/v1/crds.go b/pkg/apis/acid.zalan.do/v1/crds.go
index da88b085..c5c4b270 100644
--- a/pkg/apis/acid.zalan.do/v1/crds.go
+++ b/pkg/apis/acid.zalan.do/v1/crds.go
@@ -1573,35 +1573,35 @@ var OperatorConfigCRDResourceValidation = apiextv1.CustomResourceValidation{
 						Properties: map[string]apiextv1.JSONSchemaProps{
 							"default_cpu_limit": {
 								Type:    "string",
-								Pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$",
+								Pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$|^$",
 							},
 							"default_cpu_request": {
 								Type:    "string",
-								Pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$",
+								Pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$|^$",
 							},
 							"default_memory_limit": {
 								Type:    "string",
-								Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$",
+								Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$|^$",
 							},
 							"default_memory_request": {
 								Type:    "string",
-								Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$",
+								Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$|^$",
 							},
 							"max_cpu_request": {
 								Type:    "string",
-								Pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$",
+								Pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$|^$",
 							},
 							"max_memory_request": {
 								Type:    "string",
-								Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$",
+								Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$|^$",
 							},
 							"min_cpu_limit": {
 								Type:    "string",
-								Pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$",
+								Pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$|^$",
 							},
 							"min_memory_limit": {
 								Type:    "string",
-								Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$",
+								Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$|^$",
 							},
 						},
 					},
diff --git a/pkg/cluster/k8sres_test.go b/pkg/cluster/k8sres_test.go
index 07c05962..bea229dd 100644
--- a/pkg/cluster/k8sres_test.go
+++ b/pkg/cluster/k8sres_test.go
@@ -2993,6 +2993,44 @@ func TestGenerateResourceRequirements(t *testing.T) {
 				ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("100Mi")},
 			},
 		},
+		{
+			subTest: "test generation of resources when min limits are all set to zero",
+			config: config.Config{
+				Resources: config.Resources{
+					ClusterLabels:        map[string]string{"application": "spilo"},
+					ClusterNameLabel:     clusterNameLabel,
+					DefaultCPURequest:    "0",
+					DefaultCPULimit:      "0",
+					MaxCPURequest:        "0",
+					MinCPULimit:          "0",
+					DefaultMemoryRequest: "0",
+					DefaultMemoryLimit:   "0",
+					MaxMemoryRequest:     "0",
+					MinMemoryLimit:       "0",
+					PodRoleLabel:         "spilo-role",
+				},
+				PodManagementPolicy:     "ordered_ready",
+				SetMemoryRequestToLimit: false,
+			},
+			pgSpec: acidv1.Postgresql{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      clusterName,
+					Namespace: namespace,
+				},
+				Spec: acidv1.PostgresSpec{
+					Resources: &acidv1.Resources{
+						ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("5m"), Memory: k8sutil.StringToPointer("5Mi")},
+					},
+					TeamID: "acid",
+					Volume: acidv1.Volume{
+						Size: "1G",
+					},
+				},
+			},
+			expectedResources: acidv1.Resources{
+				ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("5m"), Memory: k8sutil.StringToPointer("5Mi")},
+			},
+		},
 		{
 			subTest: "test matchLimitsWithRequestsIfSmaller",
 			config: config.Config{
-- 
GitLab