diff --git a/charts/postgres-operator/values-crd.yaml b/charts/postgres-operator/values-crd.yaml index bb40011ed..13079e299 100644 --- a/charts/postgres-operator/values-crd.yaml +++ b/charts/postgres-operator/values-crd.yaml @@ -274,9 +274,9 @@ configConnectionPool: connection_pool_mode: "transaction" # default resources connection_pool_default_cpu_request: "100m" - connection_pool_default_memory_request: "100M" + connection_pool_default_memory_request: "100Mi" connection_pool_default_cpu_limit: "100m" - connection_pool_default_memory_limit: "100M" + connection_pool_default_memory_limit: "100Mi" rbac: # Specifies whether RBAC resources should be created diff --git a/charts/postgres-operator/values.yaml b/charts/postgres-operator/values.yaml index 1a028addd..5d36e85ee 100644 --- a/charts/postgres-operator/values.yaml +++ b/charts/postgres-operator/values.yaml @@ -251,9 +251,9 @@ configConnectionPool: connection_pool_mode: "transaction" # default resources connection_pool_default_cpu_request: "100m" - connection_pool_default_memory_request: "100M" + connection_pool_default_memory_request: "100Mi" connection_pool_default_cpu_limit: "100m" - connection_pool_default_memory_limit: "100M" + connection_pool_default_memory_limit: "100Mi" rbac: # Specifies whether RBAC resources should be created diff --git a/docs/reference/cluster_manifest.md b/docs/reference/cluster_manifest.md index da4756ca6..4c5ce2f9c 100644 --- a/docs/reference/cluster_manifest.md +++ b/docs/reference/cluster_manifest.md @@ -372,7 +372,7 @@ configuration for connection pool. If this section is not empty, a connection pool will be created for a database even if `enableConnectionPool` is not present. -* **number_of_instances** +* **numberOfInstances** How many instances of connection pool to create. * **mode** @@ -384,5 +384,8 @@ present. * **user** User to create for connection pool to be able to connect to a database. +* **dockerImage** + Which docker image to use for connection pool deployment. + * **resources** Resource configuration for connection pool deployment. diff --git a/manifests/postgresql.crd.yaml b/manifests/postgresql.crd.yaml index caee35ab0..c809533a4 100644 --- a/manifests/postgresql.crd.yaml +++ b/manifests/postgresql.crd.yaml @@ -77,6 +77,9 @@ spec: type: string mode: type: string + enum: + - "session" + - "transaction" numberOfInstances: type: integer minimum: 1 @@ -208,22 +211,6 @@ spec: type: string replicaLoadBalancer: # deprecated type: boolean - connectionPool: - type: object - properties: - schema: - type: string - user: - type: string - number_of_instances: - type: integer - dockerImage: - type: string - mode: - type: string - enum: - - "session" - - "transaction" resources: type: object required: diff --git a/pkg/apis/acid.zalan.do/v1/crds.go b/pkg/apis/acid.zalan.do/v1/crds.go index 7cc7385f7..fe00189cc 100644 --- a/pkg/apis/acid.zalan.do/v1/crds.go +++ b/pkg/apis/acid.zalan.do/v1/crds.go @@ -184,6 +184,14 @@ var PostgresCRDResourceValidation = apiextv1beta1.CustomResourceValidation{ }, "mode": { Type: "string", + Enum: []apiextv1beta1.JSON{ + { + Raw: []byte(`"session"`), + }, + { + Raw: []byte(`"transaction"`), + }, + }, }, "numberOfInstances": { Type: "integer", diff --git a/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go b/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go index bfdf61eda..0c4ff42b8 100644 --- a/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go +++ b/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go @@ -1,5 +1,7 @@ package v1 +// Operator configuration CRD definition, please use snake_case for field names. + import ( "github.com/zalando/postgres-operator/pkg/util/config" @@ -159,10 +161,10 @@ type ConnectionPoolConfiguration struct { User string `json:"connection_pool_user,omitempty"` Image string `json:"connection_pool_image,omitempty"` Mode string `json:"connection_pool_mode,omitempty"` - DefaultCPURequest string `name:"connection_pool_default_cpu_request,omitempty"` - DefaultMemoryRequest string `name:"connection_pool_default_memory_request,omitempty"` - DefaultCPULimit string `name:"connection_pool_default_cpu_limit,omitempty"` - DefaultMemoryLimit string `name:"connection_pool_default_memory_limit,omitempty"` + DefaultCPURequest string `json:"connection_pool_default_cpu_request,omitempty"` + DefaultMemoryRequest string `json:"connection_pool_default_memory_request,omitempty"` + DefaultCPULimit string `json:"connection_pool_default_cpu_limit,omitempty"` + DefaultMemoryLimit string `json:"connection_pool_default_memory_limit,omitempty"` } // OperatorLogicalBackupConfiguration defines configuration for logical backup diff --git a/pkg/apis/acid.zalan.do/v1/postgresql_type.go b/pkg/apis/acid.zalan.do/v1/postgresql_type.go index 2679f51e1..315154da2 100644 --- a/pkg/apis/acid.zalan.do/v1/postgresql_type.go +++ b/pkg/apis/acid.zalan.do/v1/postgresql_type.go @@ -1,5 +1,7 @@ package v1 +// Postgres CRD definition, please use CamelCase for field names. + import ( "time" @@ -27,7 +29,7 @@ type PostgresSpec struct { Patroni `json:"patroni,omitempty"` Resources `json:"resources,omitempty"` - EnableConnectionPool bool `json:"enableConnectionPool,omitempty"` + EnableConnectionPool *bool `json:"enableConnectionPool,omitempty"` ConnectionPool *ConnectionPool `json:"connectionPool,omitempty"` TeamID string `json:"teamId"` @@ -169,7 +171,7 @@ type PostgresStatus struct { // makes sense to expose. E.g. pool size (min/max boundaries), max client // connections etc. type ConnectionPool struct { - NumberOfInstances *int32 `json:"number_of_instances,omitempty"` + NumberOfInstances *int32 `json:"numberOfInstances,omitempty"` Schema string `json:"schema,omitempty"` User string `json:"user,omitempty"` Mode string `json:"mode,omitempty"` diff --git a/pkg/apis/acid.zalan.do/v1/register.go b/pkg/apis/acid.zalan.do/v1/register.go index 34def209d..1c30e35fb 100644 --- a/pkg/apis/acid.zalan.do/v1/register.go +++ b/pkg/apis/acid.zalan.do/v1/register.go @@ -10,8 +10,7 @@ import ( // APIVersion of the `postgresql` and `operator` CRDs const ( - APIVersion = "v1" - PostgresqlKind = "postgresql" + APIVersion = "v1" ) var ( @@ -43,7 +42,7 @@ func addKnownTypes(scheme *runtime.Scheme) error { // AddKnownType assumes derives the type kind from the type name, which is always uppercase. // For our CRDs we use lowercase names historically, therefore we have to supply the name separately. // TODO: User uppercase CRDResourceKind of our types in the next major API version - scheme.AddKnownTypeWithName(SchemeGroupVersion.WithKind(PostgresqlKind), &Postgresql{}) + scheme.AddKnownTypeWithName(SchemeGroupVersion.WithKind("postgresql"), &Postgresql{}) scheme.AddKnownTypeWithName(SchemeGroupVersion.WithKind("postgresqlList"), &PostgresqlList{}) scheme.AddKnownTypeWithName(SchemeGroupVersion.WithKind("OperatorConfiguration"), &OperatorConfiguration{}) diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index 3f09e4e82..de70e1477 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -49,7 +49,7 @@ type Config struct { PodServiceAccountRoleBinding *rbacv1beta1.RoleBinding } -type ConnectionPoolResources struct { +type ConnectionPoolObjects struct { Deployment *appsv1.Deployment Service *v1.Service } @@ -59,7 +59,7 @@ type kubeResources struct { Endpoints map[PostgresRole]*v1.Endpoints Secrets map[types.UID]*v1.Secret Statefulset *appsv1.StatefulSet - ConnectionPool *ConnectionPoolResources + ConnectionPool *ConnectionPoolObjects PodDisruptionBudget *policybeta1.PodDisruptionBudget //Pods are treated separately //PVCs are treated separately diff --git a/pkg/cluster/k8sres_test.go b/pkg/cluster/k8sres_test.go index c26e04b96..4b0a31628 100644 --- a/pkg/cluster/k8sres_test.go +++ b/pkg/cluster/k8sres_test.go @@ -541,8 +541,8 @@ func TestConnPoolPodSpec(t *testing.T) { ConnectionPool: config.ConnectionPool{ ConnPoolDefaultCPURequest: "100m", ConnPoolDefaultCPULimit: "100m", - ConnPoolDefaultMemoryRequest: "100M", - ConnPoolDefaultMemoryLimit: "100M", + ConnPoolDefaultMemoryRequest: "100Mi", + ConnPoolDefaultMemoryLimit: "100Mi", }, }, }, k8sutil.KubernetesClient{}, acidv1.Postgresql{}, logger) @@ -666,8 +666,8 @@ func TestConnPoolDeploymentSpec(t *testing.T) { ConnectionPool: config.ConnectionPool{ ConnPoolDefaultCPURequest: "100m", ConnPoolDefaultCPULimit: "100m", - ConnPoolDefaultMemoryRequest: "100M", - ConnPoolDefaultMemoryLimit: "100M", + ConnPoolDefaultMemoryRequest: "100Mi", + ConnPoolDefaultMemoryLimit: "100Mi", }, }, }, k8sutil.KubernetesClient{}, acidv1.Postgresql{}, logger) @@ -767,8 +767,8 @@ func TestConnPoolServiceSpec(t *testing.T) { ConnectionPool: config.ConnectionPool{ ConnPoolDefaultCPURequest: "100m", ConnPoolDefaultCPULimit: "100m", - ConnPoolDefaultMemoryRequest: "100M", - ConnPoolDefaultMemoryLimit: "100M", + ConnPoolDefaultMemoryRequest: "100Mi", + ConnPoolDefaultMemoryLimit: "100Mi", }, }, }, k8sutil.KubernetesClient{}, acidv1.Postgresql{}, logger) diff --git a/pkg/cluster/resources.go b/pkg/cluster/resources.go index e44d50800..46be0af4b 100644 --- a/pkg/cluster/resources.go +++ b/pkg/cluster/resources.go @@ -97,7 +97,7 @@ func (c *Cluster) createStatefulSet() (*appsv1.StatefulSet, error) { // // After that create all the objects for connection pool, namely a deployment // with a chosen pooler and a service to expose it. -func (c *Cluster) createConnectionPool(lookup InstallFunction) (*ConnectionPoolResources, error) { +func (c *Cluster) createConnectionPool(lookup InstallFunction) (*ConnectionPoolObjects, error) { var msg string c.setProcessName("creating connection pool") @@ -144,7 +144,7 @@ func (c *Cluster) createConnectionPool(lookup InstallFunction) (*ConnectionPoolR return nil, err } - c.ConnectionPool = &ConnectionPoolResources{ + c.ConnectionPool = &ConnectionPoolObjects{ Deployment: deployment, Service: service, } diff --git a/pkg/cluster/resources_test.go b/pkg/cluster/resources_test.go index 7c52addad..d0cecf841 100644 --- a/pkg/cluster/resources_test.go +++ b/pkg/cluster/resources_test.go @@ -15,6 +15,10 @@ func mockInstallLookupFunction(schema string, user string) error { return nil } +func boolToPointer(value bool) *bool { + return &value +} + func TestConnPoolCreationAndDeletion(t *testing.T) { testName := "Test connection pool creation" var cluster = New( @@ -28,8 +32,8 @@ func TestConnPoolCreationAndDeletion(t *testing.T) { ConnectionPool: config.ConnectionPool{ ConnPoolDefaultCPURequest: "100m", ConnPoolDefaultCPULimit: "100m", - ConnPoolDefaultMemoryRequest: "100M", - ConnPoolDefaultMemoryLimit: "100M", + ConnPoolDefaultMemoryRequest: "100Mi", + ConnPoolDefaultMemoryLimit: "100Mi", }, }, }, k8sutil.NewMockKubernetesClient(), acidv1.Postgresql{}, logger) @@ -77,8 +81,8 @@ func TestNeedConnPool(t *testing.T) { ConnectionPool: config.ConnectionPool{ ConnPoolDefaultCPURequest: "100m", ConnPoolDefaultCPULimit: "100m", - ConnPoolDefaultMemoryRequest: "100M", - ConnPoolDefaultMemoryLimit: "100M", + ConnPoolDefaultMemoryRequest: "100Mi", + ConnPoolDefaultMemoryLimit: "100Mi", }, }, }, k8sutil.NewMockKubernetesClient(), acidv1.Postgresql{}, logger) @@ -93,7 +97,7 @@ func TestNeedConnPool(t *testing.T) { } cluster.Spec = acidv1.PostgresSpec{ - EnableConnectionPool: true, + EnableConnectionPool: boolToPointer(true), } if !cluster.needConnectionPool() { diff --git a/pkg/cluster/sync.go b/pkg/cluster/sync.go index b59bf5533..f49638794 100644 --- a/pkg/cluster/sync.go +++ b/pkg/cluster/sync.go @@ -618,7 +618,7 @@ func (c *Cluster) syncLogicalBackupJob() error { func (c *Cluster) syncConnectionPool(oldSpec, newSpec *acidv1.Postgresql) error { if c.ConnectionPool == nil { c.logger.Warning("Connection pool resources are empty") - c.ConnectionPool = &ConnectionPoolResources{} + c.ConnectionPool = &ConnectionPoolObjects{} } deployment, err := c.KubeClient. diff --git a/pkg/cluster/sync_test.go b/pkg/cluster/sync_test.go index c6928a64e..4de75880c 100644 --- a/pkg/cluster/sync_test.go +++ b/pkg/cluster/sync_test.go @@ -54,8 +54,8 @@ func TestConnPoolSynchronization(t *testing.T) { ConnectionPool: config.ConnectionPool{ ConnPoolDefaultCPURequest: "100m", ConnPoolDefaultCPULimit: "100m", - ConnPoolDefaultMemoryRequest: "100M", - ConnPoolDefaultMemoryLimit: "100M", + ConnPoolDefaultMemoryRequest: "100Mi", + ConnPoolDefaultMemoryLimit: "100Mi", }, }, }, k8sutil.KubernetesClient{}, acidv1.Postgresql{}, logger) diff --git a/pkg/cluster/util.go b/pkg/cluster/util.go index d2dd11586..3e53ffd45 100644 --- a/pkg/cluster/util.go +++ b/pkg/cluster/util.go @@ -497,5 +497,9 @@ func (c *Cluster) patroniUsesKubernetes() bool { } func (c *Cluster) needConnectionPool() bool { - return c.Spec.ConnectionPool != nil || c.Spec.EnableConnectionPool == true + if c.Spec.EnableConnectionPool == nil { + return c.Spec.ConnectionPool != nil + } else { + return *c.Spec.EnableConnectionPool + } } diff --git a/pkg/util/constants/pooler.go b/pkg/util/constants/pooler.go index b25a12a6c..4d5edaa57 100644 --- a/pkg/util/constants/pooler.go +++ b/pkg/util/constants/pooler.go @@ -5,9 +5,9 @@ const ( ConnectionPoolUserName = "pooler" ConnectionPoolSchemaName = "pooler" ConnectionPoolDefaultType = "pgbouncer" - ConnectionPoolDefaultMode = "transition" + ConnectionPoolDefaultMode = "transaction" ConnectionPoolDefaultCpuRequest = "100m" ConnectionPoolDefaultCpuLimit = "100m" - ConnectionPoolDefaultMemoryRequest = "100M" - ConnectionPoolDefaultMemoryLimit = "100M" + ConnectionPoolDefaultMemoryRequest = "100Mi" + ConnectionPoolDefaultMemoryLimit = "100Mi" )