allow empty resources when defaults are empty (#2524)

* allow empty resources when defaults are empty
* update codegen
* add more unit tests and remove internal resources defaults
* a unit test for min limit and raising to request
* uncomment defaults in example configmap
* simplifying pooler pod generation unit test
This commit is contained in:
Felix Kunde 2024-02-09 07:35:53 +01:00 committed by GitHub
parent bf5db676b1
commit 29ea863faf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 317 additions and 224 deletions

View File

@ -365,19 +365,15 @@ spec:
default_cpu_limit: default_cpu_limit:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "1"
default_cpu_request: default_cpu_request:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "100m"
default_memory_limit: default_memory_limit:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "500Mi"
default_memory_request: default_memory_request:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "100Mi"
max_cpu_request: max_cpu_request:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
@ -387,11 +383,9 @@ spec:
min_cpu_limit: min_cpu_limit:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "250m"
min_memory_limit: min_memory_limit:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "250Mi"
timeouts: timeouts:
type: object type: object
properties: properties:
@ -672,19 +666,15 @@ spec:
connection_pooler_default_cpu_limit: connection_pooler_default_cpu_limit:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "1"
connection_pooler_default_cpu_request: connection_pooler_default_cpu_request:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "500m"
connection_pooler_default_memory_limit: connection_pooler_default_memory_limit:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "100Mi"
connection_pooler_default_memory_request: connection_pooler_default_memory_request:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "100Mi"
patroni: patroni:
type: object type: object
properties: properties:

View File

@ -549,19 +549,19 @@ CRD-based configuration.
* **default_cpu_request** * **default_cpu_request**
CPU request value for the Postgres containers, unless overridden by CPU request value for the Postgres containers, unless overridden by
cluster-specific settings. The default is `100m`. cluster-specific settings. Empty string or `0` disables the default.
* **default_memory_request** * **default_memory_request**
memory request value for the Postgres containers, unless overridden by memory request value for the Postgres containers, unless overridden by
cluster-specific settings. The default is `100Mi`. cluster-specific settings. Empty string or `0` disables the default.
* **default_cpu_limit** * **default_cpu_limit**
CPU limits for the Postgres containers, unless overridden by cluster-specific CPU limits for the Postgres containers, unless overridden by cluster-specific
settings. The default is `1`. settings. Empty string or `0` disables the default.
* **default_memory_limit** * **default_memory_limit**
memory limits for the Postgres containers, unless overridden by cluster-specific memory limits for the Postgres containers, unless overridden by cluster-specific
settings. The default is `500Mi`. settings. Empty string or `0` disables the default.
* **max_cpu_request** * **max_cpu_request**
optional upper boundary for CPU request optional upper boundary for CPU request
@ -571,11 +571,11 @@ CRD-based configuration.
* **min_cpu_limit** * **min_cpu_limit**
hard CPU minimum what we consider to be required to properly run Postgres hard CPU minimum what we consider to be required to properly run Postgres
clusters with Patroni on Kubernetes. The default is `250m`. clusters with Patroni on Kubernetes.
* **min_memory_limit** * **min_memory_limit**
hard memory minimum what we consider to be required to properly run Postgres hard memory minimum what we consider to be required to properly run Postgres
clusters with Patroni on Kubernetes. The default is `250Mi`. clusters with Patroni on Kubernetes.
## Patroni options ## Patroni options
@ -1026,5 +1026,4 @@ operator being able to provide some reasonable defaults.
**connection_pooler_default_memory_reques** **connection_pooler_default_memory_reques**
**connection_pooler_default_cpu_limit** **connection_pooler_default_cpu_limit**
**connection_pooler_default_memory_limit** **connection_pooler_default_memory_limit**
Default resource configuration for connection pooler deployment. The internal Default resource configuration for connection pooler deployment.
default for memory request and limit is `100Mi`, for CPU it is `500m` and `1`.

View File

@ -689,6 +689,9 @@ The minimum limits to properly run the `postgresql` resource are configured to
manifest the operator will raise the limits to the configured minimum values. manifest the operator will raise the limits to the configured minimum values.
If no resources are defined in the manifest they will be obtained from the If no resources are defined in the manifest they will be obtained from the
configured [default requests](reference/operator_parameters.md#kubernetes-resource-requests). configured [default requests](reference/operator_parameters.md#kubernetes-resource-requests).
If neither defaults nor minimum limits are configured the operator will not
specify any resources and it's up to K8s (or your own) admission hooks to
handle it.
### HugePages support ### HugePages support

View File

@ -13,10 +13,10 @@ data:
cluster_history_entries: "1000" cluster_history_entries: "1000"
cluster_labels: application:spilo cluster_labels: application:spilo
cluster_name_label: cluster-name cluster_name_label: cluster-name
# connection_pooler_default_cpu_limit: "1" connection_pooler_default_cpu_limit: "1"
# connection_pooler_default_cpu_request: "500m" connection_pooler_default_cpu_request: "500m"
# connection_pooler_default_memory_limit: 100Mi connection_pooler_default_memory_limit: 100Mi
# connection_pooler_default_memory_request: 100Mi connection_pooler_default_memory_request: 100Mi
connection_pooler_image: "registry.opensource.zalan.do/acid/pgbouncer:master-32" connection_pooler_image: "registry.opensource.zalan.do/acid/pgbouncer:master-32"
# connection_pooler_max_db_connections: 60 # connection_pooler_max_db_connections: 60
# connection_pooler_mode: "transaction" # connection_pooler_mode: "transaction"
@ -28,10 +28,10 @@ data:
# custom_pod_annotations: "keya:valuea,keyb:valueb" # custom_pod_annotations: "keya:valuea,keyb:valueb"
db_hosted_zone: db.example.com db_hosted_zone: db.example.com
debug_logging: "true" debug_logging: "true"
# default_cpu_limit: "1" default_cpu_limit: "1"
# default_cpu_request: 100m default_cpu_request: 100m
# default_memory_limit: 500Mi default_memory_limit: 500Mi
# default_memory_request: 100Mi default_memory_request: 100Mi
# delete_annotation_date_key: delete-date # delete_annotation_date_key: delete-date
# delete_annotation_name_key: delete-clustername # delete_annotation_name_key: delete-clustername
docker_image: ghcr.io/zalando/spilo-15:3.0-p1 docker_image: ghcr.io/zalando/spilo-15:3.0-p1

View File

@ -363,19 +363,15 @@ spec:
default_cpu_limit: default_cpu_limit:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "1"
default_cpu_request: default_cpu_request:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "100m"
default_memory_limit: default_memory_limit:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "500Mi"
default_memory_request: default_memory_request:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "100Mi"
max_cpu_request: max_cpu_request:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
@ -385,11 +381,9 @@ spec:
min_cpu_limit: min_cpu_limit:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "250m"
min_memory_limit: min_memory_limit:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "250Mi"
timeouts: timeouts:
type: object type: object
properties: properties:
@ -670,19 +664,15 @@ spec:
connection_pooler_default_cpu_limit: connection_pooler_default_cpu_limit:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "1"
connection_pooler_default_cpu_request: connection_pooler_default_cpu_request:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "500m"
connection_pooler_default_memory_limit: connection_pooler_default_memory_limit:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "100Mi"
connection_pooler_default_memory_request: connection_pooler_default_memory_request:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "100Mi"
patroni: patroni:
type: object type: object
properties: properties:

View File

@ -153,10 +153,10 @@ type PostgresqlParam struct {
// ResourceDescription describes CPU and memory resources defined for a cluster. // ResourceDescription describes CPU and memory resources defined for a cluster.
type ResourceDescription struct { type ResourceDescription struct {
CPU string `json:"cpu"` CPU *string `json:"cpu,omitempty"`
Memory string `json:"memory"` Memory *string `json:"memory,omitempty"`
HugePages2Mi *string `json:"hugepages-2Mi"` HugePages2Mi *string `json:"hugepages-2Mi,omitempty"`
HugePages1Gi *string `json:"hugepages-1Gi"` HugePages1Gi *string `json:"hugepages-1Gi,omitempty"`
} }
// Resources describes requests and limits for the cluster resouces. // Resources describes requests and limits for the cluster resouces.
@ -260,7 +260,7 @@ type Stream struct {
// StreamTable defines properties of outbox tables for FabricEventStreams // StreamTable defines properties of outbox tables for FabricEventStreams
type StreamTable struct { type StreamTable struct {
EventType string `json:"eventType"` EventType string `json:"eventType"`
RecoveryEventType string `json:"recoveryEventType"` RecoveryEventType string `json:"recoveryEventType,omitempty"`
IdColumn *string `json:"idColumn,omitempty"` IdColumn *string `json:"idColumn,omitempty"`
PayloadColumn *string `json:"payloadColumn,omitempty"` PayloadColumn *string `json:"payloadColumn,omitempty"`
} }

View File

@ -26,6 +26,10 @@ var parseTimeTests = []struct {
{"expect error as minute is out of range", "23:69", metav1.Now(), errors.New(`parsing time "23:69": minute out of range`)}, {"expect error as minute is out of range", "23:69", metav1.Now(), errors.New(`parsing time "23:69": minute out of range`)},
} }
func stringToPointer(str string) *string {
return &str
}
var parseWeekdayTests = []struct { var parseWeekdayTests = []struct {
about string about string
in string in string
@ -301,8 +305,8 @@ var unmarshalCluster = []struct {
Slots: map[string]map[string]string{"permanent_logical_1": {"type": "logical", "database": "foo", "plugin": "pgoutput"}}, Slots: map[string]map[string]string{"permanent_logical_1": {"type": "logical", "database": "foo", "plugin": "pgoutput"}},
}, },
Resources: &Resources{ Resources: &Resources{
ResourceRequests: ResourceDescription{CPU: "10m", Memory: "50Mi"}, ResourceRequests: ResourceDescription{CPU: stringToPointer("10m"), Memory: stringToPointer("50Mi")},
ResourceLimits: ResourceDescription{CPU: "300m", Memory: "3000Mi"}, ResourceLimits: ResourceDescription{CPU: stringToPointer("300m"), Memory: stringToPointer("3000Mi")},
}, },
TeamID: "acid", TeamID: "acid",

View File

@ -1165,6 +1165,16 @@ func (in *PreparedSchema) DeepCopy() *PreparedSchema {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ResourceDescription) DeepCopyInto(out *ResourceDescription) { func (in *ResourceDescription) DeepCopyInto(out *ResourceDescription) {
*out = *in *out = *in
if in.CPU != nil {
in, out := &in.CPU, &out.CPU
*out = new(string)
**out = **in
}
if in.Memory != nil {
in, out := &in.Memory, &out.Memory
*out = new(string)
**out = **in
}
if in.HugePages2Mi != nil { if in.HugePages2Mi != nil {
in, out := &in.HugePages2Mi, &out.HugePages2Mi in, out := &in.HugePages2Mi, &out.HugePages2Mi
*out = new(string) *out = new(string)

View File

@ -161,8 +161,8 @@ func TestStatefulSetAnnotations(t *testing.T) {
spec := acidv1.PostgresSpec{ spec := acidv1.PostgresSpec{
TeamID: "myapp", NumberOfInstances: 1, TeamID: "myapp", NumberOfInstances: 1,
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
}, },
Volume: acidv1.Volume{ Volume: acidv1.Volume{
Size: "1G", Size: "1G",
@ -184,8 +184,8 @@ func TestStatefulSetUpdateWithEnv(t *testing.T) {
oldSpec := &acidv1.PostgresSpec{ oldSpec := &acidv1.PostgresSpec{
TeamID: "myapp", NumberOfInstances: 1, TeamID: "myapp", NumberOfInstances: 1,
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
}, },
Volume: acidv1.Volume{ Volume: acidv1.Volume{
Size: "1G", Size: "1G",

View File

@ -821,12 +821,12 @@ func (c *Cluster) needSyncConnectionPoolerDefaults(Config *Config, spec *acidv1.
func makeDefaultConnectionPoolerResources(config *config.Config) acidv1.Resources { func makeDefaultConnectionPoolerResources(config *config.Config) acidv1.Resources {
defaultRequests := acidv1.ResourceDescription{ defaultRequests := acidv1.ResourceDescription{
CPU: config.ConnectionPooler.ConnectionPoolerDefaultCPURequest, CPU: &config.ConnectionPooler.ConnectionPoolerDefaultCPURequest,
Memory: config.ConnectionPooler.ConnectionPoolerDefaultMemoryRequest, Memory: &config.ConnectionPooler.ConnectionPoolerDefaultMemoryRequest,
} }
defaultLimits := acidv1.ResourceDescription{ defaultLimits := acidv1.ResourceDescription{
CPU: config.ConnectionPooler.ConnectionPoolerDefaultCPULimit, CPU: &config.ConnectionPooler.ConnectionPoolerDefaultCPULimit,
Memory: config.ConnectionPooler.ConnectionPoolerDefaultMemoryLimit, Memory: &config.ConnectionPooler.ConnectionPoolerDefaultMemoryLimit,
} }
return acidv1.Resources{ return acidv1.Resources{

View File

@ -2,7 +2,6 @@ package cluster
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"strings" "strings"
"testing" "testing"
@ -711,47 +710,42 @@ func TestConnectionPoolerPodSpec(t *testing.T) {
noCheck := func(cluster *Cluster, podSpec *v1.PodTemplateSpec, role PostgresRole) error { return nil } noCheck := func(cluster *Cluster, podSpec *v1.PodTemplateSpec, role PostgresRole) error { return nil }
tests := []struct { tests := []struct {
subTest string subTest string
spec *acidv1.PostgresSpec spec *acidv1.PostgresSpec
expected error cluster *Cluster
cluster *Cluster check func(cluster *Cluster, podSpec *v1.PodTemplateSpec, role PostgresRole) error
check func(cluster *Cluster, podSpec *v1.PodTemplateSpec, role PostgresRole) error
}{ }{
{ {
subTest: "default configuration", subTest: "default configuration",
spec: &acidv1.PostgresSpec{ spec: &acidv1.PostgresSpec{
ConnectionPooler: &acidv1.ConnectionPooler{}, ConnectionPooler: &acidv1.ConnectionPooler{},
}, },
expected: nil, cluster: cluster,
cluster: cluster, check: noCheck,
check: noCheck,
}, },
{ {
subTest: "pooler uses pod service account", subTest: "pooler uses pod service account",
spec: &acidv1.PostgresSpec{ spec: &acidv1.PostgresSpec{
ConnectionPooler: &acidv1.ConnectionPooler{}, ConnectionPooler: &acidv1.ConnectionPooler{},
}, },
expected: nil, cluster: cluster,
cluster: cluster, check: testServiceAccount,
check: testServiceAccount,
}, },
{ {
subTest: "no default resources", subTest: "no default resources",
spec: &acidv1.PostgresSpec{ spec: &acidv1.PostgresSpec{
ConnectionPooler: &acidv1.ConnectionPooler{}, ConnectionPooler: &acidv1.ConnectionPooler{},
}, },
expected: errors.New(`could not generate resource requirements: could not fill resource requests: could not parse default CPU quantity: quantities must match the regular expression '^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$'`), cluster: clusterNoDefaultRes,
cluster: clusterNoDefaultRes, check: noCheck,
check: noCheck,
}, },
{ {
subTest: "default resources are set", subTest: "default resources are set",
spec: &acidv1.PostgresSpec{ spec: &acidv1.PostgresSpec{
ConnectionPooler: &acidv1.ConnectionPooler{}, ConnectionPooler: &acidv1.ConnectionPooler{},
}, },
expected: nil, cluster: cluster,
cluster: cluster, check: testResources,
check: testResources,
}, },
{ {
subTest: "labels for service", subTest: "labels for service",
@ -759,30 +753,23 @@ func TestConnectionPoolerPodSpec(t *testing.T) {
ConnectionPooler: &acidv1.ConnectionPooler{}, ConnectionPooler: &acidv1.ConnectionPooler{},
EnableReplicaConnectionPooler: boolToPointer(true), EnableReplicaConnectionPooler: boolToPointer(true),
}, },
expected: nil, cluster: cluster,
cluster: cluster, check: testLabels,
check: testLabels,
}, },
{ {
subTest: "required envs", subTest: "required envs",
spec: &acidv1.PostgresSpec{ spec: &acidv1.PostgresSpec{
ConnectionPooler: &acidv1.ConnectionPooler{}, ConnectionPooler: &acidv1.ConnectionPooler{},
}, },
expected: nil, cluster: cluster,
cluster: cluster, check: testEnvs,
check: testEnvs,
}, },
} }
for _, role := range [2]PostgresRole{Master, Replica} { for _, role := range [2]PostgresRole{Master, Replica} {
for _, tt := range tests { for _, tt := range tests {
podSpec, err := tt.cluster.generateConnectionPoolerPodTemplate(role) podSpec, _ := tt.cluster.generateConnectionPoolerPodTemplate(role)
if err != tt.expected && err.Error() != tt.expected.Error() { err := tt.check(cluster, podSpec, role)
t.Errorf("%s [%s]: Could not generate pod template,\n %+v, expected\n %+v",
testName, tt.subTest, err, tt.expected)
}
err = tt.check(cluster, podSpec, role)
if err != nil { if err != nil {
t.Errorf("%s [%s]: Pod spec is incorrect, %+v", t.Errorf("%s [%s]: Pod spec is incorrect, %+v",
testName, tt.subTest, err) testName, tt.subTest, err)
@ -973,8 +960,8 @@ func TestPoolerTLS(t *testing.T) {
TeamID: "myapp", NumberOfInstances: 1, TeamID: "myapp", NumberOfInstances: 1,
EnableConnectionPooler: util.True(), EnableConnectionPooler: util.True(),
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
}, },
Volume: acidv1.Volume{ Volume: acidv1.Volume{
Size: "1G", Size: "1G",

View File

@ -21,6 +21,7 @@ import (
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
"golang.org/x/exp/maps" "golang.org/x/exp/maps"
"golang.org/x/exp/slices"
batchv1 "k8s.io/api/batch/v1" batchv1 "k8s.io/api/batch/v1"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
@ -126,12 +127,12 @@ func (c *Cluster) podDisruptionBudgetName() string {
func makeDefaultResources(config *config.Config) acidv1.Resources { func makeDefaultResources(config *config.Config) acidv1.Resources {
defaultRequests := acidv1.ResourceDescription{ defaultRequests := acidv1.ResourceDescription{
CPU: config.Resources.DefaultCPURequest, CPU: &config.Resources.DefaultCPURequest,
Memory: config.Resources.DefaultMemoryRequest, Memory: &config.Resources.DefaultMemoryRequest,
} }
defaultLimits := acidv1.ResourceDescription{ defaultLimits := acidv1.ResourceDescription{
CPU: config.Resources.DefaultCPULimit, CPU: &config.Resources.DefaultCPULimit,
Memory: config.Resources.DefaultMemoryLimit, Memory: &config.Resources.DefaultMemoryLimit,
} }
return acidv1.Resources{ return acidv1.Resources{
@ -143,12 +144,12 @@ func makeDefaultResources(config *config.Config) acidv1.Resources {
func makeLogicalBackupResources(config *config.Config) acidv1.Resources { func makeLogicalBackupResources(config *config.Config) acidv1.Resources {
logicalBackupResourceRequests := acidv1.ResourceDescription{ logicalBackupResourceRequests := acidv1.ResourceDescription{
CPU: config.LogicalBackup.LogicalBackupCPURequest, CPU: &config.LogicalBackup.LogicalBackupCPURequest,
Memory: config.LogicalBackup.LogicalBackupMemoryRequest, Memory: &config.LogicalBackup.LogicalBackupMemoryRequest,
} }
logicalBackupResourceLimits := acidv1.ResourceDescription{ logicalBackupResourceLimits := acidv1.ResourceDescription{
CPU: config.LogicalBackup.LogicalBackupCPULimit, CPU: &config.LogicalBackup.LogicalBackupCPULimit,
Memory: config.LogicalBackup.LogicalBackupMemoryLimit, Memory: &config.LogicalBackup.LogicalBackupMemoryLimit,
} }
return acidv1.Resources{ return acidv1.Resources{
@ -214,7 +215,9 @@ func (c *Cluster) enforceMaxResourceRequests(resources *v1.ResourceRequirements)
return fmt.Errorf("could not compare defined CPU request %s for %q container with configured maximum value %s: %v", return fmt.Errorf("could not compare defined CPU request %s for %q container with configured maximum value %s: %v",
cpuRequest.String(), constants.PostgresContainerName, maxCPURequest, err) cpuRequest.String(), constants.PostgresContainerName, maxCPURequest, err)
} }
resources.Requests[v1.ResourceCPU] = maxCPU if !maxCPU.IsZero() {
resources.Requests[v1.ResourceCPU] = maxCPU
}
memoryRequest := resources.Requests[v1.ResourceMemory] memoryRequest := resources.Requests[v1.ResourceMemory]
maxMemoryRequest := c.OpConfig.MaxMemoryRequest maxMemoryRequest := c.OpConfig.MaxMemoryRequest
@ -223,7 +226,9 @@ func (c *Cluster) enforceMaxResourceRequests(resources *v1.ResourceRequirements)
return fmt.Errorf("could not compare defined memory request %s for %q container with configured maximum value %s: %v", return fmt.Errorf("could not compare defined memory request %s for %q container with configured maximum value %s: %v",
memoryRequest.String(), constants.PostgresContainerName, maxMemoryRequest, err) memoryRequest.String(), constants.PostgresContainerName, maxMemoryRequest, err)
} }
resources.Requests[v1.ResourceMemory] = maxMemory if !maxMemory.IsZero() {
resources.Requests[v1.ResourceMemory] = maxMemory
}
return nil return nil
} }
@ -240,30 +245,53 @@ func setMemoryRequestToLimit(resources *v1.ResourceRequirements, containerName s
} }
} }
func matchLimitsWithRequestsIfSmaller(resources *v1.ResourceRequirements, containerName string, logger *logrus.Entry) {
requests := resources.Requests
limits := resources.Limits
requestCPU, cpuRequestsExists := requests[v1.ResourceCPU]
limitCPU, cpuLimitExists := limits[v1.ResourceCPU]
if cpuRequestsExists && cpuLimitExists && limitCPU.Cmp(requestCPU) == -1 {
logger.Warningf("CPU limit of %s for %q container is increased to match CPU requests of %s", limitCPU.String(), containerName, requestCPU.String())
resources.Limits[v1.ResourceCPU] = requestCPU
}
requestMemory, memoryRequestsExists := requests[v1.ResourceMemory]
limitMemory, memoryLimitExists := limits[v1.ResourceMemory]
if memoryRequestsExists && memoryLimitExists && limitMemory.Cmp(requestMemory) == -1 {
logger.Warningf("memory limit of %s for %q container is increased to match memory requests of %s", limitMemory.String(), containerName, requestMemory.String())
resources.Limits[v1.ResourceMemory] = requestMemory
}
}
func fillResourceList(spec acidv1.ResourceDescription, defaults acidv1.ResourceDescription) (v1.ResourceList, error) { func fillResourceList(spec acidv1.ResourceDescription, defaults acidv1.ResourceDescription) (v1.ResourceList, error) {
var err error var err error
requests := v1.ResourceList{} requests := v1.ResourceList{}
emptyResourceExamples := []string{"", "0", "null"}
if spec.CPU != "" { if spec.CPU != nil && !slices.Contains(emptyResourceExamples, *spec.CPU) {
requests[v1.ResourceCPU], err = resource.ParseQuantity(spec.CPU) requests[v1.ResourceCPU], err = resource.ParseQuantity(*spec.CPU)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not parse CPU quantity: %v", err) return nil, fmt.Errorf("could not parse CPU quantity: %v", err)
} }
} else { } else {
requests[v1.ResourceCPU], err = resource.ParseQuantity(defaults.CPU) if defaults.CPU != nil && !slices.Contains(emptyResourceExamples, *defaults.CPU) {
if err != nil { requests[v1.ResourceCPU], err = resource.ParseQuantity(*defaults.CPU)
return nil, fmt.Errorf("could not parse default CPU quantity: %v", err) if err != nil {
return nil, fmt.Errorf("could not parse default CPU quantity: %v", err)
}
} }
} }
if spec.Memory != "" { if spec.Memory != nil && !slices.Contains(emptyResourceExamples, *spec.Memory) {
requests[v1.ResourceMemory], err = resource.ParseQuantity(spec.Memory) requests[v1.ResourceMemory], err = resource.ParseQuantity(*spec.Memory)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not parse memory quantity: %v", err) return nil, fmt.Errorf("could not parse memory quantity: %v", err)
} }
} else { } else {
requests[v1.ResourceMemory], err = resource.ParseQuantity(defaults.Memory) if defaults.Memory != nil && !slices.Contains(emptyResourceExamples, *defaults.Memory) {
if err != nil { requests[v1.ResourceMemory], err = resource.ParseQuantity(*defaults.Memory)
return nil, fmt.Errorf("could not parse default memory quantity: %v", err) if err != nil {
return nil, fmt.Errorf("could not parse default memory quantity: %v", err)
}
} }
} }
@ -314,6 +342,10 @@ func (c *Cluster) generateResourceRequirements(
} }
} }
// make sure after reflecting default and enforcing min limit values we don't have requests > limits
matchLimitsWithRequestsIfSmaller(&result, containerName, c.logger)
// vice versa set memory requests to limit if option is enabled
if c.OpConfig.SetMemoryRequestToLimit { if c.OpConfig.SetMemoryRequestToLimit {
setMemoryRequestToLimit(&result, containerName, c.logger) setMemoryRequestToLimit(&result, containerName, c.logger)
} }
@ -1208,12 +1240,12 @@ func getBucketScopeSuffix(uid string) string {
func makeResources(cpuRequest, memoryRequest, cpuLimit, memoryLimit string) acidv1.Resources { func makeResources(cpuRequest, memoryRequest, cpuLimit, memoryLimit string) acidv1.Resources {
return acidv1.Resources{ return acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{ ResourceRequests: acidv1.ResourceDescription{
CPU: cpuRequest, CPU: &cpuRequest,
Memory: memoryRequest, Memory: &memoryRequest,
}, },
ResourceLimits: acidv1.ResourceDescription{ ResourceLimits: acidv1.ResourceDescription{
CPU: cpuLimit, CPU: &cpuLimit,
Memory: memoryLimit, Memory: &memoryLimit,
}, },
} }
} }

View File

@ -1421,8 +1421,8 @@ func TestNodeAffinity(t *testing.T) {
return acidv1.PostgresSpec{ return acidv1.PostgresSpec{
TeamID: "myapp", NumberOfInstances: 1, TeamID: "myapp", NumberOfInstances: 1,
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
}, },
Volume: acidv1.Volume{ Volume: acidv1.Volume{
Size: "1G", Size: "1G",
@ -1514,8 +1514,8 @@ func TestPodAffinity(t *testing.T) {
Spec: acidv1.PostgresSpec{ Spec: acidv1.PostgresSpec{
NumberOfInstances: 1, NumberOfInstances: 1,
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
}, },
Volume: acidv1.Volume{ Volume: acidv1.Volume{
Size: "1G", Size: "1G",
@ -1658,8 +1658,8 @@ func TestTLS(t *testing.T) {
Spec: acidv1.PostgresSpec{ Spec: acidv1.PostgresSpec{
TeamID: "myapp", NumberOfInstances: 1, TeamID: "myapp", NumberOfInstances: 1,
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
}, },
Volume: acidv1.Volume{ Volume: acidv1.Volume{
Size: "1G", Size: "1G",
@ -1899,8 +1899,8 @@ func TestAdditionalVolume(t *testing.T) {
Spec: acidv1.PostgresSpec{ Spec: acidv1.PostgresSpec{
TeamID: "myapp", NumberOfInstances: 1, TeamID: "myapp", NumberOfInstances: 1,
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
}, },
Volume: acidv1.Volume{ Volume: acidv1.Volume{
Size: "1G", Size: "1G",
@ -1975,8 +1975,8 @@ func TestVolumeSelector(t *testing.T) {
TeamID: "myapp", TeamID: "myapp",
NumberOfInstances: 0, NumberOfInstances: 0,
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
}, },
Volume: volume, Volume: volume,
} }
@ -2107,8 +2107,8 @@ func TestSidecars(t *testing.T) {
}, },
TeamID: "myapp", NumberOfInstances: 1, TeamID: "myapp", NumberOfInstances: 1,
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
}, },
Volume: acidv1.Volume{ Volume: acidv1.Volume{
Size: "1G", Size: "1G",
@ -2120,8 +2120,8 @@ func TestSidecars(t *testing.T) {
acidv1.Sidecar{ acidv1.Sidecar{
Name: "cluster-specific-sidecar-with-resources", Name: "cluster-specific-sidecar-with-resources",
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "210m", Memory: "0.8Gi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("210m"), Memory: k8sutil.StringToPointer("0.8Gi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "510m", Memory: "1.4Gi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("510m"), Memory: k8sutil.StringToPointer("1.4Gi")},
}, },
}, },
acidv1.Sidecar{ acidv1.Sidecar{
@ -2419,8 +2419,8 @@ func TestGenerateService(t *testing.T) {
spec = acidv1.PostgresSpec{ spec = acidv1.PostgresSpec{
TeamID: "myapp", NumberOfInstances: 1, TeamID: "myapp", NumberOfInstances: 1,
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
}, },
Volume: acidv1.Volume{ Volume: acidv1.Volume{
Size: "1G", Size: "1G",
@ -2432,8 +2432,8 @@ func TestGenerateService(t *testing.T) {
acidv1.Sidecar{ acidv1.Sidecar{
Name: "cluster-specific-sidecar-with-resources", Name: "cluster-specific-sidecar-with-resources",
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "210m", Memory: "0.8Gi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("210m"), Memory: k8sutil.StringToPointer("0.8Gi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "510m", Memory: "1.4Gi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("510m"), Memory: k8sutil.StringToPointer("1.4Gi")},
}, },
}, },
acidv1.Sidecar{ acidv1.Sidecar{
@ -2646,8 +2646,8 @@ func TestEnableLoadBalancers(t *testing.T) {
EnableReplicaPoolerLoadBalancer: util.False(), EnableReplicaPoolerLoadBalancer: util.False(),
NumberOfInstances: 1, NumberOfInstances: 1,
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
}, },
TeamID: "acid", TeamID: "acid",
Volume: acidv1.Volume{ Volume: acidv1.Volume{
@ -2693,8 +2693,8 @@ func TestEnableLoadBalancers(t *testing.T) {
EnableReplicaPoolerLoadBalancer: util.True(), EnableReplicaPoolerLoadBalancer: util.True(),
NumberOfInstances: 1, NumberOfInstances: 1,
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "10"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("10")},
}, },
TeamID: "acid", TeamID: "acid",
Volume: acidv1.Volume{ Volume: acidv1.Volume{
@ -2786,8 +2786,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
}, },
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "100m", Memory: "100Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("100Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "500Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("500Mi")},
}, },
}, },
{ {
@ -2815,8 +2815,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
}, },
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "100m", Memory: "100Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("100Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "500Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("500Mi")},
}, },
}, },
{ {
@ -2833,7 +2833,7 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
Spec: acidv1.PostgresSpec{ Spec: acidv1.PostgresSpec{
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "50m", Memory: "50Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("50m"), Memory: k8sutil.StringToPointer("50Mi")},
}, },
TeamID: "acid", TeamID: "acid",
Volume: acidv1.Volume{ Volume: acidv1.Volume{
@ -2842,8 +2842,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
}, },
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "50m", Memory: "50Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("50m"), Memory: k8sutil.StringToPointer("50Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "500Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("500Mi")},
}, },
}, },
{ {
@ -2860,8 +2860,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
Spec: acidv1.PostgresSpec{ Spec: acidv1.PostgresSpec{
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{Memory: "100Mi"}, ResourceRequests: acidv1.ResourceDescription{Memory: k8sutil.StringToPointer("100Mi")},
ResourceLimits: acidv1.ResourceDescription{Memory: "1Gi"}, ResourceLimits: acidv1.ResourceDescription{Memory: k8sutil.StringToPointer("1Gi")},
}, },
TeamID: "acid", TeamID: "acid",
Volume: acidv1.Volume{ Volume: acidv1.Volume{
@ -2870,8 +2870,97 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
}, },
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "100m", Memory: "100Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("100Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "1Gi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("1Gi")},
},
},
{
subTest: "test generation of resources when default is not defined",
config: config.Config{
Resources: config.Resources{
ClusterLabels: map[string]string{"application": "spilo"},
ClusterNameLabel: clusterNameLabel,
DefaultCPURequest: "100m",
DefaultMemoryRequest: "100Mi",
PodRoleLabel: "spilo-role",
},
PodManagementPolicy: "ordered_ready",
SetMemoryRequestToLimit: false,
},
pgSpec: acidv1.Postgresql{
ObjectMeta: metav1.ObjectMeta{
Name: clusterName,
Namespace: namespace,
},
Spec: acidv1.PostgresSpec{
TeamID: "acid",
Volume: acidv1.Volume{
Size: "1G",
},
},
},
expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("100Mi")},
},
},
{
subTest: "test matchLimitsWithRequestsIfSmaller",
config: config.Config{
Resources: configResources,
PodManagementPolicy: "ordered_ready",
SetMemoryRequestToLimit: false,
},
pgSpec: acidv1.Postgresql{
ObjectMeta: metav1.ObjectMeta{
Name: clusterName,
Namespace: namespace,
},
Spec: acidv1.PostgresSpec{
Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{Memory: k8sutil.StringToPointer("750Mi")},
ResourceLimits: acidv1.ResourceDescription{Memory: k8sutil.StringToPointer("300Mi")},
},
TeamID: "acid",
Volume: acidv1.Volume{
Size: "1G",
},
},
},
expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("750Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("750Mi")},
},
},
{
subTest: "defaults are not defined but minimum limit is",
config: config.Config{
Resources: config.Resources{
ClusterLabels: map[string]string{"application": "spilo"},
ClusterNameLabel: clusterNameLabel,
MinMemoryLimit: "250Mi",
PodRoleLabel: "spilo-role",
},
PodManagementPolicy: "ordered_ready",
SetMemoryRequestToLimit: false,
},
pgSpec: acidv1.Postgresql{
ObjectMeta: metav1.ObjectMeta{
Name: clusterName,
Namespace: namespace,
},
Spec: acidv1.PostgresSpec{
Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{Memory: k8sutil.StringToPointer("500Mi")},
},
TeamID: "acid",
Volume: acidv1.Volume{
Size: "1G",
},
},
},
expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{Memory: k8sutil.StringToPointer("500Mi")},
ResourceLimits: acidv1.ResourceDescription{Memory: k8sutil.StringToPointer("500Mi")},
}, },
}, },
{ {
@ -2888,8 +2977,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
Spec: acidv1.PostgresSpec{ Spec: acidv1.PostgresSpec{
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{Memory: "200Mi"}, ResourceRequests: acidv1.ResourceDescription{Memory: k8sutil.StringToPointer("200Mi")},
ResourceLimits: acidv1.ResourceDescription{Memory: "300Mi"}, ResourceLimits: acidv1.ResourceDescription{Memory: k8sutil.StringToPointer("300Mi")},
}, },
TeamID: "acid", TeamID: "acid",
Volume: acidv1.Volume{ Volume: acidv1.Volume{
@ -2898,8 +2987,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
}, },
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "100m", Memory: "300Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("300Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "300Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("300Mi")},
}, },
}, },
{ {
@ -2919,8 +3008,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
acidv1.Sidecar{ acidv1.Sidecar{
Name: sidecarName, Name: sidecarName,
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "10m", Memory: "10Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("10m"), Memory: k8sutil.StringToPointer("10Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "100m", Memory: "100Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("100Mi")},
}, },
}, },
}, },
@ -2931,8 +3020,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
}, },
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "10m", Memory: "100Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("10m"), Memory: k8sutil.StringToPointer("100Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "100m", Memory: "100Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("100Mi")},
}, },
}, },
{ {
@ -2949,8 +3038,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
Spec: acidv1.PostgresSpec{ Spec: acidv1.PostgresSpec{
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "10m", Memory: "250Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("10m"), Memory: k8sutil.StringToPointer("250Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "400m", Memory: "800Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("400m"), Memory: k8sutil.StringToPointer("800Mi")},
}, },
TeamID: "acid", TeamID: "acid",
Volume: acidv1.Volume{ Volume: acidv1.Volume{
@ -2959,8 +3048,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
}, },
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "10m", Memory: "250Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("10m"), Memory: k8sutil.StringToPointer("250Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "400m", Memory: "800Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("400m"), Memory: k8sutil.StringToPointer("800Mi")},
}, },
}, },
{ {
@ -2977,8 +3066,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
Spec: acidv1.PostgresSpec{ Spec: acidv1.PostgresSpec{
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "100m", Memory: "100Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("100Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "200m", Memory: "200Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("200m"), Memory: k8sutil.StringToPointer("200Mi")},
}, },
TeamID: "acid", TeamID: "acid",
Volume: acidv1.Volume{ Volume: acidv1.Volume{
@ -2987,8 +3076,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
}, },
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "100m", Memory: "100Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("100Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "250m", Memory: "250Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("250m"), Memory: k8sutil.StringToPointer("250Mi")},
}, },
}, },
{ {
@ -3008,8 +3097,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
acidv1.Sidecar{ acidv1.Sidecar{
Name: sidecarName, Name: sidecarName,
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "10m", Memory: "10Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("10m"), Memory: k8sutil.StringToPointer("10Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "100m", Memory: "100Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("100Mi")},
}, },
}, },
}, },
@ -3020,8 +3109,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
}, },
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "10m", Memory: "10Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("10m"), Memory: k8sutil.StringToPointer("10Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "100m", Memory: "100Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("100Mi")},
}, },
}, },
{ {
@ -3038,8 +3127,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
Spec: acidv1.PostgresSpec{ Spec: acidv1.PostgresSpec{
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "1", Memory: "2Gi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("2Gi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "2", Memory: "4Gi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("2"), Memory: k8sutil.StringToPointer("4Gi")},
}, },
TeamID: "acid", TeamID: "acid",
Volume: acidv1.Volume{ Volume: acidv1.Volume{
@ -3048,8 +3137,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
}, },
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "500m", Memory: "1Gi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("500m"), Memory: k8sutil.StringToPointer("1Gi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "2", Memory: "4Gi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("2"), Memory: k8sutil.StringToPointer("4Gi")},
}, },
}, },
{ {
@ -3066,8 +3155,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
Spec: acidv1.PostgresSpec{ Spec: acidv1.PostgresSpec{
Resources: &acidv1.Resources{ Resources: &acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{Memory: "500Mi"}, ResourceRequests: acidv1.ResourceDescription{Memory: k8sutil.StringToPointer("500Mi")},
ResourceLimits: acidv1.ResourceDescription{Memory: "2Gi"}, ResourceLimits: acidv1.ResourceDescription{Memory: k8sutil.StringToPointer("2Gi")},
}, },
TeamID: "acid", TeamID: "acid",
Volume: acidv1.Volume{ Volume: acidv1.Volume{
@ -3076,8 +3165,8 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
}, },
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "100m", Memory: "1Gi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("1Gi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "2Gi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("2Gi")},
}, },
}, },
{ {
@ -3104,12 +3193,12 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{ ResourceRequests: acidv1.ResourceDescription{
CPU: "100m", CPU: k8sutil.StringToPointer("100m"),
Memory: "100Mi", Memory: k8sutil.StringToPointer("100Mi"),
}, },
ResourceLimits: acidv1.ResourceDescription{ ResourceLimits: acidv1.ResourceDescription{
CPU: "1", CPU: k8sutil.StringToPointer("1"),
Memory: "500Mi", Memory: k8sutil.StringToPointer("500Mi"),
}, },
}, },
}, },
@ -3143,14 +3232,14 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{ ResourceRequests: acidv1.ResourceDescription{
CPU: "100m", CPU: k8sutil.StringToPointer("100m"),
Memory: "100Mi", Memory: k8sutil.StringToPointer("100Mi"),
HugePages2Mi: k8sutil.StringToPointer("128Mi"), HugePages2Mi: k8sutil.StringToPointer("128Mi"),
HugePages1Gi: k8sutil.StringToPointer("1Gi"), HugePages1Gi: k8sutil.StringToPointer("1Gi"),
}, },
ResourceLimits: acidv1.ResourceDescription{ ResourceLimits: acidv1.ResourceDescription{
CPU: "1", CPU: k8sutil.StringToPointer("1"),
Memory: "500Mi", Memory: k8sutil.StringToPointer("500Mi"),
HugePages2Mi: k8sutil.StringToPointer("256Mi"), HugePages2Mi: k8sutil.StringToPointer("256Mi"),
HugePages1Gi: k8sutil.StringToPointer("2Gi"), HugePages1Gi: k8sutil.StringToPointer("2Gi"),
}, },
@ -3192,14 +3281,14 @@ func TestGenerateResourceRequirements(t *testing.T) {
}, },
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{ ResourceRequests: acidv1.ResourceDescription{
CPU: "100m", CPU: k8sutil.StringToPointer("100m"),
Memory: "100Mi", Memory: k8sutil.StringToPointer("100Mi"),
HugePages2Mi: k8sutil.StringToPointer("128Mi"), HugePages2Mi: k8sutil.StringToPointer("128Mi"),
HugePages1Gi: k8sutil.StringToPointer("1Gi"), HugePages1Gi: k8sutil.StringToPointer("1Gi"),
}, },
ResourceLimits: acidv1.ResourceDescription{ ResourceLimits: acidv1.ResourceDescription{
CPU: "1", CPU: k8sutil.StringToPointer("1"),
Memory: "500Mi", Memory: k8sutil.StringToPointer("500Mi"),
HugePages2Mi: k8sutil.StringToPointer("256Mi"), HugePages2Mi: k8sutil.StringToPointer("256Mi"),
HugePages1Gi: k8sutil.StringToPointer("2Gi"), HugePages1Gi: k8sutil.StringToPointer("2Gi"),
}, },
@ -3269,8 +3358,8 @@ func TestGenerateLogicalBackupJob(t *testing.T) {
expectedSchedule: "30 00 * * *", expectedSchedule: "30 00 * * *",
expectedJobName: "logical-backup-acid-test-cluster", expectedJobName: "logical-backup-acid-test-cluster",
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "100m", Memory: "100Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("100Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "500Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("500Mi")},
}, },
expectedLabel: map[string]string{configResources.ClusterNameLabel: clusterName, "team": teamId}, expectedLabel: map[string]string{configResources.ClusterNameLabel: clusterName, "team": teamId},
expectedAnnotation: nil, expectedAnnotation: nil,
@ -3294,8 +3383,8 @@ func TestGenerateLogicalBackupJob(t *testing.T) {
expectedSchedule: "30 00 * * 7", expectedSchedule: "30 00 * * 7",
expectedJobName: "lb-acid-test-cluster", expectedJobName: "lb-acid-test-cluster",
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "10m", Memory: "50Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("10m"), Memory: k8sutil.StringToPointer("50Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "300m", Memory: "300Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("300m"), Memory: k8sutil.StringToPointer("300Mi")},
}, },
expectedLabel: map[string]string{configResources.ClusterNameLabel: clusterName, "team": teamId}, expectedLabel: map[string]string{configResources.ClusterNameLabel: clusterName, "team": teamId},
expectedAnnotation: nil, expectedAnnotation: nil,
@ -3317,8 +3406,8 @@ func TestGenerateLogicalBackupJob(t *testing.T) {
expectedSchedule: "30 00 * * *", expectedSchedule: "30 00 * * *",
expectedJobName: "acid-test-cluster", expectedJobName: "acid-test-cluster",
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "50m", Memory: "100Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("50m"), Memory: k8sutil.StringToPointer("100Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "250m", Memory: "500Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("250m"), Memory: k8sutil.StringToPointer("500Mi")},
}, },
expectedLabel: map[string]string{configResources.ClusterNameLabel: clusterName, "team": teamId}, expectedLabel: map[string]string{configResources.ClusterNameLabel: clusterName, "team": teamId},
expectedAnnotation: nil, expectedAnnotation: nil,
@ -3340,8 +3429,8 @@ func TestGenerateLogicalBackupJob(t *testing.T) {
expectedSchedule: "30 00 * * *", expectedSchedule: "30 00 * * *",
expectedJobName: "test-long-prefix-so-name-must-be-trimmed-acid-test-c", expectedJobName: "test-long-prefix-so-name-must-be-trimmed-acid-test-c",
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "100m", Memory: "200Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("200Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "200Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("200Mi")},
}, },
expectedLabel: map[string]string{configResources.ClusterNameLabel: clusterName, "team": teamId}, expectedLabel: map[string]string{configResources.ClusterNameLabel: clusterName, "team": teamId},
expectedAnnotation: nil, expectedAnnotation: nil,
@ -3362,8 +3451,8 @@ func TestGenerateLogicalBackupJob(t *testing.T) {
expectedJobName: "acid-test-cluster", expectedJobName: "acid-test-cluster",
expectedSchedule: "", expectedSchedule: "",
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "100m", Memory: "100Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("100Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "500Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("500Mi")},
}, },
expectedLabel: map[string]string{"labelKey": "labelValue", "cluster-name": clusterName, "team": teamId}, expectedLabel: map[string]string{"labelKey": "labelValue", "cluster-name": clusterName, "team": teamId},
expectedAnnotation: nil, expectedAnnotation: nil,
@ -3384,8 +3473,8 @@ func TestGenerateLogicalBackupJob(t *testing.T) {
expectedJobName: "acid-test-cluster", expectedJobName: "acid-test-cluster",
expectedSchedule: "", expectedSchedule: "",
expectedResources: acidv1.Resources{ expectedResources: acidv1.Resources{
ResourceRequests: acidv1.ResourceDescription{CPU: "100m", Memory: "100Mi"}, ResourceRequests: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("100m"), Memory: k8sutil.StringToPointer("100Mi")},
ResourceLimits: acidv1.ResourceDescription{CPU: "1", Memory: "500Mi"}, ResourceLimits: acidv1.ResourceDescription{CPU: k8sutil.StringToPointer("1"), Memory: k8sutil.StringToPointer("500Mi")},
}, },
expectedLabel: map[string]string{configResources.ClusterNameLabel: clusterName, "team": teamId}, expectedLabel: map[string]string{configResources.ClusterNameLabel: clusterName, "team": teamId},
expectedAnnotation: map[string]string{"annotationKey": "annotationValue"}, expectedAnnotation: map[string]string{"annotationKey": "annotationValue"},

View File

@ -130,12 +130,12 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
result.PodToleration = fromCRD.Kubernetes.PodToleration result.PodToleration = fromCRD.Kubernetes.PodToleration
// Postgres Pod resources // Postgres Pod resources
result.DefaultCPURequest = util.Coalesce(fromCRD.PostgresPodResources.DefaultCPURequest, "100m") result.DefaultCPURequest = fromCRD.PostgresPodResources.DefaultCPURequest
result.DefaultMemoryRequest = util.Coalesce(fromCRD.PostgresPodResources.DefaultMemoryRequest, "100Mi") result.DefaultMemoryRequest = fromCRD.PostgresPodResources.DefaultMemoryRequest
result.DefaultCPULimit = util.Coalesce(fromCRD.PostgresPodResources.DefaultCPULimit, "1") result.DefaultCPULimit = fromCRD.PostgresPodResources.DefaultCPULimit
result.DefaultMemoryLimit = util.Coalesce(fromCRD.PostgresPodResources.DefaultMemoryLimit, "500Mi") result.DefaultMemoryLimit = fromCRD.PostgresPodResources.DefaultMemoryLimit
result.MinCPULimit = util.Coalesce(fromCRD.PostgresPodResources.MinCPULimit, "250m") result.MinCPULimit = fromCRD.PostgresPodResources.MinCPULimit
result.MinMemoryLimit = util.Coalesce(fromCRD.PostgresPodResources.MinMemoryLimit, "250Mi") result.MinMemoryLimit = fromCRD.PostgresPodResources.MinMemoryLimit
result.MaxCPURequest = fromCRD.PostgresPodResources.MaxCPURequest result.MaxCPURequest = fromCRD.PostgresPodResources.MaxCPURequest
result.MaxMemoryRequest = fromCRD.PostgresPodResources.MaxMemoryRequest result.MaxMemoryRequest = fromCRD.PostgresPodResources.MaxMemoryRequest
@ -265,21 +265,10 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
fromCRD.ConnectionPooler.Mode, fromCRD.ConnectionPooler.Mode,
constants.ConnectionPoolerDefaultMode) constants.ConnectionPoolerDefaultMode)
result.ConnectionPooler.ConnectionPoolerDefaultCPURequest = util.Coalesce( result.ConnectionPooler.ConnectionPoolerDefaultCPURequest = fromCRD.ConnectionPooler.DefaultCPURequest
fromCRD.ConnectionPooler.DefaultCPURequest, result.ConnectionPooler.ConnectionPoolerDefaultMemoryRequest = fromCRD.ConnectionPooler.DefaultMemoryRequest
constants.ConnectionPoolerDefaultCpuRequest) result.ConnectionPooler.ConnectionPoolerDefaultCPULimit = fromCRD.ConnectionPooler.DefaultCPULimit
result.ConnectionPooler.ConnectionPoolerDefaultMemoryLimit = fromCRD.ConnectionPooler.DefaultMemoryLimit
result.ConnectionPooler.ConnectionPoolerDefaultMemoryRequest = util.Coalesce(
fromCRD.ConnectionPooler.DefaultMemoryRequest,
constants.ConnectionPoolerDefaultMemoryRequest)
result.ConnectionPooler.ConnectionPoolerDefaultCPULimit = util.Coalesce(
fromCRD.ConnectionPooler.DefaultCPULimit,
constants.ConnectionPoolerDefaultCpuLimit)
result.ConnectionPooler.ConnectionPoolerDefaultMemoryLimit = util.Coalesce(
fromCRD.ConnectionPooler.DefaultMemoryLimit,
constants.ConnectionPoolerDefaultMemoryLimit)
result.ConnectionPooler.MaxDBConnections = util.CoalesceInt32( result.ConnectionPooler.MaxDBConnections = util.CoalesceInt32(
fromCRD.ConnectionPooler.MaxDBConnections, fromCRD.ConnectionPooler.MaxDBConnections,

View File

@ -48,12 +48,12 @@ type Resources struct {
DeleteAnnotationNameKey string `name:"delete_annotation_name_key"` DeleteAnnotationNameKey string `name:"delete_annotation_name_key"`
PodRoleLabel string `name:"pod_role_label" default:"spilo-role"` PodRoleLabel string `name:"pod_role_label" default:"spilo-role"`
PodToleration map[string]string `name:"toleration" default:""` PodToleration map[string]string `name:"toleration" default:""`
DefaultCPURequest string `name:"default_cpu_request" default:"100m"` DefaultCPURequest string `name:"default_cpu_request"`
DefaultMemoryRequest string `name:"default_memory_request" default:"100Mi"` DefaultMemoryRequest string `name:"default_memory_request"`
DefaultCPULimit string `name:"default_cpu_limit" default:"1"` DefaultCPULimit string `name:"default_cpu_limit"`
DefaultMemoryLimit string `name:"default_memory_limit" default:"500Mi"` DefaultMemoryLimit string `name:"default_memory_limit"`
MinCPULimit string `name:"min_cpu_limit" default:"250m"` MinCPULimit string `name:"min_cpu_limit"`
MinMemoryLimit string `name:"min_memory_limit" default:"250Mi"` MinMemoryLimit string `name:"min_memory_limit"`
MaxCPURequest string `name:"max_cpu_request"` MaxCPURequest string `name:"max_cpu_request"`
MaxMemoryRequest string `name:"max_memory_request"` MaxMemoryRequest string `name:"max_memory_request"`
PodEnvironmentConfigMap spec.NamespacedName `name:"pod_environment_configmap"` PodEnvironmentConfigMap spec.NamespacedName `name:"pod_environment_configmap"`
@ -155,10 +155,10 @@ type ConnectionPooler struct {
Image string `name:"connection_pooler_image" default:"registry.opensource.zalan.do/acid/pgbouncer"` Image string `name:"connection_pooler_image" default:"registry.opensource.zalan.do/acid/pgbouncer"`
Mode string `name:"connection_pooler_mode" default:"transaction"` Mode string `name:"connection_pooler_mode" default:"transaction"`
MaxDBConnections *int32 `name:"connection_pooler_max_db_connections" default:"60"` MaxDBConnections *int32 `name:"connection_pooler_max_db_connections" default:"60"`
ConnectionPoolerDefaultCPURequest string `name:"connection_pooler_default_cpu_request" default:"500m"` ConnectionPoolerDefaultCPURequest string `name:"connection_pooler_default_cpu_request"`
ConnectionPoolerDefaultMemoryRequest string `name:"connection_pooler_default_memory_request" default:"100Mi"` ConnectionPoolerDefaultMemoryRequest string `name:"connection_pooler_default_memory_request"`
ConnectionPoolerDefaultCPULimit string `name:"connection_pooler_default_cpu_limit" default:"1"` ConnectionPoolerDefaultCPULimit string `name:"connection_pooler_default_cpu_limit"`
ConnectionPoolerDefaultMemoryLimit string `name:"connection_pooler_default_memory_limit" default:"100Mi"` ConnectionPoolerDefaultMemoryLimit string `name:"connection_pooler_default_memory_limit"`
} }
// Config describes operator config // Config describes operator config