Merge branch 'master' into add-topologySpreadConstraints

This commit is contained in:
Felix Kunde 2025-10-15 15:18:39 +02:00 committed by GitHub
commit 3a8fc1b259
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 142 additions and 43 deletions

View File

@ -195,12 +195,14 @@ from numerous escape characters in the latter log entry, view it in CLI with
used internally in K8s. used internally in K8s.
The StatefulSet is replaced if the following properties change: The StatefulSet is replaced if the following properties change:
- annotations - annotations
- volumeClaimTemplates - volumeClaimTemplates
- template volumes - template volumes
The StatefulSet is replaced and a rolling updates is triggered if the following The StatefulSet is replaced and a rolling updates is triggered if the following
properties differ between the old and new state: properties differ between the old and new state:
- container name, ports, image, resources, env, envFrom, securityContext and volumeMounts - container name, ports, image, resources, env, envFrom, securityContext and volumeMounts
- template labels, annotations, service account, securityContext, affinity, priority class and termination grace period - template labels, annotations, service account, securityContext, affinity, priority class and termination grace period
@ -898,6 +900,7 @@ services:
There are multiple options to specify service annotations that will be merged There are multiple options to specify service annotations that will be merged
with each other and override in the following order (where latter take with each other and override in the following order (where latter take
precedence): precedence):
1. Default annotations if LoadBalancer is enabled 1. Default annotations if LoadBalancer is enabled
2. Globally configured `custom_service_annotations` 2. Globally configured `custom_service_annotations`
3. `serviceAnnotations` specified in the cluster manifest 3. `serviceAnnotations` specified in the cluster manifest

View File

@ -16,7 +16,7 @@ under the ~/go/src sub directories.
Given the schema above, the Postgres Operator source code located at Given the schema above, the Postgres Operator source code located at
`github.com/zalando/postgres-operator` should be put at `github.com/zalando/postgres-operator` should be put at
-`~/go/src/github.com/zalando/postgres-operator`. `~/go/src/github.com/zalando/postgres-operator`.
```bash ```bash
export GOPATH=~/go export GOPATH=~/go
@ -105,6 +105,7 @@ and K8s-like APIs for its custom resource definitions, namely the
Postgres CRD and the operator CRD. The usage of the code generation follows Postgres CRD and the operator CRD. The usage of the code generation follows
conventions from the K8s community. Relevant scripts live in the `hack` conventions from the K8s community. Relevant scripts live in the `hack`
directory: directory:
* `update-codegen.sh` triggers code generation for the APIs defined in `pkg/apis/acid.zalan.do/`, * `update-codegen.sh` triggers code generation for the APIs defined in `pkg/apis/acid.zalan.do/`,
* `verify-codegen.sh` checks if the generated code is up-to-date (to be used within CI). * `verify-codegen.sh` checks if the generated code is up-to-date (to be used within CI).
@ -112,6 +113,7 @@ The `/pkg/generated/` contains the resultant code. To make these scripts work,
you may need to `export GOPATH=$(go env GOPATH)` you may need to `export GOPATH=$(go env GOPATH)`
References for code generation are: References for code generation are:
* [Relevant pull request](https://github.com/zalando/postgres-operator/pull/369) * [Relevant pull request](https://github.com/zalando/postgres-operator/pull/369)
See comments there for minor issues that can sometimes broke the generation process. See comments there for minor issues that can sometimes broke the generation process.
* [Code generator source code](https://github.com/kubernetes/code-generator) * [Code generator source code](https://github.com/kubernetes/code-generator)
@ -315,6 +317,7 @@ precedence.
Update the following Go files that obtain the configuration parameter from the Update the following Go files that obtain the configuration parameter from the
manifest files: manifest files:
* [operator_configuration_type.go](https://github.com/zalando/postgres-operator/blob/master/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go) * [operator_configuration_type.go](https://github.com/zalando/postgres-operator/blob/master/pkg/apis/acid.zalan.do/v1/operator_configuration_type.go)
* [operator_config.go](https://github.com/zalando/postgres-operator/blob/master/pkg/controller/operator_config.go) * [operator_config.go](https://github.com/zalando/postgres-operator/blob/master/pkg/controller/operator_config.go)
* [config.go](https://github.com/zalando/postgres-operator/blob/master/pkg/util/config/config.go) * [config.go](https://github.com/zalando/postgres-operator/blob/master/pkg/util/config/config.go)
@ -323,6 +326,7 @@ Postgres manifest parameters are defined in the [api package](https://github.com
The operator behavior has to be implemented at least in [k8sres.go](https://github.com/zalando/postgres-operator/blob/master/pkg/cluster/k8sres.go). The operator behavior has to be implemented at least in [k8sres.go](https://github.com/zalando/postgres-operator/blob/master/pkg/cluster/k8sres.go).
Validation of CRD parameters is controlled in [crds.go](https://github.com/zalando/postgres-operator/blob/master/pkg/apis/acid.zalan.do/v1/crds.go). Validation of CRD parameters is controlled in [crds.go](https://github.com/zalando/postgres-operator/blob/master/pkg/apis/acid.zalan.do/v1/crds.go).
Please, reflect your changes in tests, for example in: Please, reflect your changes in tests, for example in:
* [config_test.go](https://github.com/zalando/postgres-operator/blob/master/pkg/util/config/config_test.go) * [config_test.go](https://github.com/zalando/postgres-operator/blob/master/pkg/util/config/config_test.go)
* [k8sres_test.go](https://github.com/zalando/postgres-operator/blob/master/pkg/cluster/k8sres_test.go) * [k8sres_test.go](https://github.com/zalando/postgres-operator/blob/master/pkg/cluster/k8sres_test.go)
* [util_test.go](https://github.com/zalando/postgres-operator/blob/master/pkg/apis/acid.zalan.do/v1/util_test.go) * [util_test.go](https://github.com/zalando/postgres-operator/blob/master/pkg/apis/acid.zalan.do/v1/util_test.go)
@ -330,6 +334,7 @@ Please, reflect your changes in tests, for example in:
### Updating manifest files ### Updating manifest files
For the CRD-based configuration, please update the following files: For the CRD-based configuration, please update the following files:
* the default [OperatorConfiguration](https://github.com/zalando/postgres-operator/blob/master/manifests/postgresql-operator-default-configuration.yaml) * the default [OperatorConfiguration](https://github.com/zalando/postgres-operator/blob/master/manifests/postgresql-operator-default-configuration.yaml)
* the CRD's [validation](https://github.com/zalando/postgres-operator/blob/master/manifests/operatorconfiguration.crd.yaml) * the CRD's [validation](https://github.com/zalando/postgres-operator/blob/master/manifests/operatorconfiguration.crd.yaml)
* the CRD's validation in the [Helm chart](https://github.com/zalando/postgres-operator/blob/master/charts/postgres-operator/crds/operatorconfigurations.yaml) * the CRD's validation in the [Helm chart](https://github.com/zalando/postgres-operator/blob/master/charts/postgres-operator/crds/operatorconfigurations.yaml)
@ -342,6 +347,7 @@ Last but no least, update the [ConfigMap](https://github.com/zalando/postgres-op
Finally, add a section for each new configuration option and/or cluster manifest Finally, add a section for each new configuration option and/or cluster manifest
parameter in the reference documents: parameter in the reference documents:
* [config reference](reference/operator_parameters.md) * [config reference](reference/operator_parameters.md)
* [manifest reference](reference/cluster_manifest.md) * [manifest reference](reference/cluster_manifest.md)

View File

@ -10,7 +10,7 @@ hence set it up first. For local tests we recommend to use one of the following
solutions: solutions:
* [minikube](https://github.com/kubernetes/minikube/releases), which creates a * [minikube](https://github.com/kubernetes/minikube/releases), which creates a
single-node K8s cluster inside a VM (requires KVM or VirtualBox), K8s cluster inside a container or VM (requires Docker, KVM, Hyper-V, HyperKit, VirtualBox, or similar),
* [kind](https://kind.sigs.k8s.io/) and [k3d](https://k3d.io), which allows creating multi-nodes K8s * [kind](https://kind.sigs.k8s.io/) and [k3d](https://k3d.io), which allows creating multi-nodes K8s
clusters running on Docker (requires Docker) clusters running on Docker (requires Docker)
@ -20,7 +20,7 @@ This quickstart assumes that you have started minikube or created a local kind
cluster. Note that you can also use built-in K8s support in the Docker Desktop cluster. Note that you can also use built-in K8s support in the Docker Desktop
for Mac to follow the steps of this tutorial. You would have to replace for Mac to follow the steps of this tutorial. You would have to replace
`minikube start` and `minikube delete` with your launch actions for the Docker `minikube start` and `minikube delete` with your launch actions for the Docker
built-in K8s support. Desktop built-in K8s support.
## Configuration Options ## Configuration Options

View File

@ -107,8 +107,13 @@ Those are top-level keys, containing both leaf keys and groups.
* **kubernetes_use_configmaps** * **kubernetes_use_configmaps**
Select if setup uses endpoints (default), or configmaps to manage leader when Select if setup uses endpoints (default), or configmaps to manage leader when
DCS is kubernetes (not etcd or similar). In OpenShift it is not possible to DCS is kubernetes (not etcd or similar). In OpenShift it is not possible to
use endpoints option, and configmaps is required. By default, use endpoints option, and configmaps is required. Starting with K8s 1.33,
`kubernetes_use_configmaps: false`, meaning endpoints will be used. endpoints are marked as deprecated. It's recommended to switch to config maps
instead. But, to do so make sure you scale the Postgres cluster down to just
one primary pod (e.g. using `max_instances` option). Otherwise, you risk
running into a split-brain scenario.
By default, `kubernetes_use_configmaps: false`, meaning endpoints will be used.
Starting from v1.16.0 the default will be changed to `true`.
* **docker_image** * **docker_image**
Spilo Docker image for Postgres instances. For production, don't rely on the Spilo Docker image for Postgres instances. For production, don't rely on the

6
go.mod
View File

@ -3,6 +3,7 @@ module github.com/zalando/postgres-operator
go 1.25.0 go 1.25.0
require ( require (
github.com/Masterminds/semver v1.5.0
github.com/aws/aws-sdk-go v1.53.8 github.com/aws/aws-sdk-go v1.53.8
github.com/golang/mock v1.6.0 github.com/golang/mock v1.6.0
github.com/lib/pq v1.10.9 github.com/lib/pq v1.10.9
@ -12,7 +13,6 @@ require (
github.com/sirupsen/logrus v1.9.3 github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
golang.org/x/crypto v0.41.0 golang.org/x/crypto v0.41.0
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.30.4 k8s.io/api v0.30.4
k8s.io/apiextensions-apiserver v0.25.9 k8s.io/apiextensions-apiserver v0.25.9
@ -21,10 +21,7 @@ require (
k8s.io/code-generator v0.25.9 k8s.io/code-generator v0.25.9
) )
require golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect
require ( require (
github.com/Masterminds/semver v1.5.0
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect
@ -62,6 +59,7 @@ require (
golang.org/x/text v0.28.0 // indirect golang.org/x/text v0.28.0 // indirect
golang.org/x/time v0.3.0 // indirect golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.36.0 // indirect golang.org/x/tools v0.36.0 // indirect
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.33.0 // indirect google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect

2
go.sum
View File

@ -121,8 +121,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=

View File

@ -122,7 +122,21 @@ function aws_upload {
function gcs_upload { function gcs_upload {
PATH_TO_BACKUP=gs://$LOGICAL_BACKUP_S3_BUCKET"/"$LOGICAL_BACKUP_S3_BUCKET_PREFIX"/"$SCOPE$LOGICAL_BACKUP_S3_BUCKET_SCOPE_SUFFIX"/logical_backups/"$(date +%s).sql.gz PATH_TO_BACKUP=gs://$LOGICAL_BACKUP_S3_BUCKET"/"$LOGICAL_BACKUP_S3_BUCKET_PREFIX"/"$SCOPE$LOGICAL_BACKUP_S3_BUCKET_SCOPE_SUFFIX"/logical_backups/"$(date +%s).sql.gz
gsutil -o Credentials:gs_service_key_file=$LOGICAL_BACKUP_GOOGLE_APPLICATION_CREDENTIALS cp - "$PATH_TO_BACKUP" #Set local LOGICAL_GOOGLE_APPLICATION_CREDENTIALS to nothing or
#value of LOGICAL_GOOGLE_APPLICATION_CREDENTIALS env var. Needed
#because `set -o nounset` is globally set
local LOGICAL_BACKUP_GOOGLE_APPLICATION_CREDENTIALS=${LOGICAL_BACKUP_GOOGLE_APPLICATION_CREDENTIALS:-}
GSUTIL_OPTIONS=("-o" "Credentials:gs_service_key_file=$LOGICAL_BACKUP_GOOGLE_APPLICATION_CREDENTIALS")
#If GOOGLE_APPLICATION_CREDENTIALS is not set try to get
#creds from metadata
if [[ -z $LOGICAL_BACKUP_GOOGLE_APPLICATION_CREDENTIALS ]]
then
GSUTIL_OPTIONS[1]="GoogleCompute:service_account=default"
fi
gsutil ${GSUTIL_OPTIONS[@]} cp - "$PATH_TO_BACKUP"
} }
function upload { function upload {

View File

@ -59,13 +59,20 @@ rules:
- get - get
- patch - patch
- update - update
# to read configuration from ConfigMaps # to read configuration from ConfigMaps and help Patroni manage the cluster if endpoints are not used
- apiGroups: - apiGroups:
- "" - ""
resources: resources:
- configmaps - configmaps
verbs: verbs:
- create
- delete
- deletecollection
- get - get
- list
- patch
- update
- watch
# to send events to the CRs # to send events to the CRs
- apiGroups: - apiGroups:
- "" - ""
@ -78,7 +85,7 @@ rules:
- patch - patch
- update - update
- watch - watch
# to manage endpoints which are also used by Patroni # to manage endpoints which are also used by Patroni (if it is using config maps)
- apiGroups: - apiGroups:
- "" - ""
resources: resources:
@ -249,7 +256,21 @@ kind: ClusterRole
metadata: metadata:
name: postgres-pod name: postgres-pod
rules: rules:
# Patroni needs to watch and manage endpoints # Patroni needs to watch and manage config maps (or endpoints)
- apiGroups:
- ""
resources:
- configmaps
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
# Patroni needs to watch and manage endpoints (or config maps)
- apiGroups: - apiGroups:
- "" - ""
resources: resources:

View File

@ -846,6 +846,14 @@ func (c *Cluster) compareServices(old, new *v1.Service) (bool, string) {
return false, "new service's owner references do not match the current ones" return false, "new service's owner references do not match the current ones"
} }
if !reflect.DeepEqual(old.Spec.Selector, new.Spec.Selector) {
return false, "new service's selector does not match the current one"
}
if old.Spec.ExternalTrafficPolicy != new.Spec.ExternalTrafficPolicy {
return false, "new service's ExternalTrafficPolicy does not match the current one"
}
return true, "" return true, ""
} }

View File

@ -1341,14 +1341,21 @@ func TestCompareEnv(t *testing.T) {
} }
} }
func newService(ann map[string]string, svcT v1.ServiceType, lbSr []string) *v1.Service { func newService(
annotations map[string]string,
svcType v1.ServiceType,
sourceRanges []string,
selector map[string]string,
policy v1.ServiceExternalTrafficPolicyType) *v1.Service {
svc := &v1.Service{ svc := &v1.Service{
Spec: v1.ServiceSpec{ Spec: v1.ServiceSpec{
Type: svcT, Selector: selector,
LoadBalancerSourceRanges: lbSr, Type: svcType,
LoadBalancerSourceRanges: sourceRanges,
ExternalTrafficPolicy: policy,
}, },
} }
svc.Annotations = ann svc.Annotations = annotations
return svc return svc
} }
@ -1365,13 +1372,18 @@ func TestCompareServices(t *testing.T) {
}, },
} }
defaultPolicy := v1.ServiceExternalTrafficPolicyTypeCluster
serviceWithOwnerReference := newService( serviceWithOwnerReference := newService(
map[string]string{ map[string]string{
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do", constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue, constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
}, },
v1.ServiceTypeClusterIP, v1.ServiceTypeClusterIP,
[]string{"128.141.0.0/16", "137.138.0.0/16"}) []string{"128.141.0.0/16", "137.138.0.0/16"},
nil,
defaultPolicy,
)
ownerRef := metav1.OwnerReference{ ownerRef := metav1.OwnerReference{
APIVersion: "acid.zalan.do/v1", APIVersion: "acid.zalan.do/v1",
@ -1397,14 +1409,16 @@ func TestCompareServices(t *testing.T) {
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue, constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
}, },
v1.ServiceTypeClusterIP, v1.ServiceTypeClusterIP,
[]string{"128.141.0.0/16", "137.138.0.0/16"}), []string{"128.141.0.0/16", "137.138.0.0/16"},
nil, defaultPolicy),
new: newService( new: newService(
map[string]string{ map[string]string{
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do", constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue, constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
}, },
v1.ServiceTypeClusterIP, v1.ServiceTypeClusterIP,
[]string{"128.141.0.0/16", "137.138.0.0/16"}), []string{"128.141.0.0/16", "137.138.0.0/16"},
nil, defaultPolicy),
match: true, match: true,
}, },
{ {
@ -1415,14 +1429,16 @@ func TestCompareServices(t *testing.T) {
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue, constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
}, },
v1.ServiceTypeClusterIP, v1.ServiceTypeClusterIP,
[]string{"128.141.0.0/16", "137.138.0.0/16"}), []string{"128.141.0.0/16", "137.138.0.0/16"},
nil, defaultPolicy),
new: newService( new: newService(
map[string]string{ map[string]string{
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do", constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue, constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
}, },
v1.ServiceTypeLoadBalancer, v1.ServiceTypeLoadBalancer,
[]string{"128.141.0.0/16", "137.138.0.0/16"}), []string{"128.141.0.0/16", "137.138.0.0/16"},
nil, defaultPolicy),
match: false, match: false,
reason: `new service's type "LoadBalancer" does not match the current one "ClusterIP"`, reason: `new service's type "LoadBalancer" does not match the current one "ClusterIP"`,
}, },
@ -1434,14 +1450,16 @@ func TestCompareServices(t *testing.T) {
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue, constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
}, },
v1.ServiceTypeLoadBalancer, v1.ServiceTypeLoadBalancer,
[]string{"128.141.0.0/16", "137.138.0.0/16"}), []string{"128.141.0.0/16", "137.138.0.0/16"},
nil, defaultPolicy),
new: newService( new: newService(
map[string]string{ map[string]string{
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do", constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue, constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
}, },
v1.ServiceTypeLoadBalancer, v1.ServiceTypeLoadBalancer,
[]string{"185.249.56.0/22"}), []string{"185.249.56.0/22"},
nil, defaultPolicy),
match: false, match: false,
reason: `new service's LoadBalancerSourceRange does not match the current one`, reason: `new service's LoadBalancerSourceRange does not match the current one`,
}, },
@ -1453,14 +1471,16 @@ func TestCompareServices(t *testing.T) {
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue, constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
}, },
v1.ServiceTypeLoadBalancer, v1.ServiceTypeLoadBalancer,
[]string{"128.141.0.0/16", "137.138.0.0/16"}), []string{"128.141.0.0/16", "137.138.0.0/16"},
nil, defaultPolicy),
new: newService( new: newService(
map[string]string{ map[string]string{
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do", constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue, constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
}, },
v1.ServiceTypeLoadBalancer, v1.ServiceTypeLoadBalancer,
[]string{}), []string{},
nil, defaultPolicy),
match: false, match: false,
reason: `new service's LoadBalancerSourceRange does not match the current one`, reason: `new service's LoadBalancerSourceRange does not match the current one`,
}, },
@ -1472,10 +1492,39 @@ func TestCompareServices(t *testing.T) {
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue, constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
}, },
v1.ServiceTypeClusterIP, v1.ServiceTypeClusterIP,
[]string{"128.141.0.0/16", "137.138.0.0/16"}), []string{"128.141.0.0/16", "137.138.0.0/16"},
nil, defaultPolicy),
new: serviceWithOwnerReference, new: serviceWithOwnerReference,
match: false, match: false,
}, },
{
about: "new service has a label selector",
current: newService(
map[string]string{},
v1.ServiceTypeClusterIP,
[]string{},
nil, defaultPolicy),
new: newService(
map[string]string{},
v1.ServiceTypeClusterIP,
[]string{},
map[string]string{"cluster-name": "clstr", "spilo-role": "master"}, defaultPolicy),
match: false,
},
{
about: "services differ on external traffic policy",
current: newService(
map[string]string{},
v1.ServiceTypeClusterIP,
[]string{},
nil, defaultPolicy),
new: newService(
map[string]string{},
v1.ServiceTypeClusterIP,
[]string{},
nil, v1.ServiceExternalTrafficPolicyTypeLocal),
match: false,
},
} }
for _, tt := range tests { for _, tt := range tests {

View File

@ -4,7 +4,9 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"maps"
"path" "path"
"slices"
"sort" "sort"
"strings" "strings"
@ -12,19 +14,16 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
appsv1 "k8s.io/api/apps/v1" appsv1 "k8s.io/api/apps/v1"
batchv1 "k8s.io/api/batch/v1"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1" policyv1 "k8s.io/api/policy/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
"golang.org/x/exp/maps"
"golang.org/x/exp/slices"
batchv1 "k8s.io/api/batch/v1"
"k8s.io/apimachinery/pkg/labels"
acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1" acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1"
"github.com/zalando/postgres-operator/pkg/spec" "github.com/zalando/postgres-operator/pkg/spec"
"github.com/zalando/postgres-operator/pkg/util" "github.com/zalando/postgres-operator/pkg/util"
@ -1941,7 +1940,7 @@ func (c *Cluster) generateSingleUserSecret(pgUser spec.PgUser) *v1.Secret {
// if secret lives in another namespace we cannot set ownerReferences // if secret lives in another namespace we cannot set ownerReferences
var ownerReferences []metav1.OwnerReference var ownerReferences []metav1.OwnerReference
if c.Config.OpConfig.EnableCrossNamespaceSecret && strings.Contains(username, ".") { if c.Config.OpConfig.EnableCrossNamespaceSecret && c.Postgresql.ObjectMeta.Namespace != pgUser.Namespace {
ownerReferences = nil ownerReferences = nil
} else { } else {
ownerReferences = c.ownerReferences() ownerReferences = c.ownerReferences()

View File

@ -3,12 +3,11 @@ package cluster
import ( import (
"context" "context"
"fmt" "fmt"
"slices"
"sort" "sort"
"strconv" "strconv"
"time" "time"
"golang.org/x/exp/slices"
appsv1 "k8s.io/api/apps/v1" appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

View File

@ -4,8 +4,10 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"maps"
"reflect" "reflect"
"regexp" "regexp"
"slices"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -15,8 +17,6 @@ import (
"github.com/zalando/postgres-operator/pkg/util" "github.com/zalando/postgres-operator/pkg/util"
"github.com/zalando/postgres-operator/pkg/util/constants" "github.com/zalando/postgres-operator/pkg/util/constants"
"github.com/zalando/postgres-operator/pkg/util/k8sutil" "github.com/zalando/postgres-operator/pkg/util/k8sutil"
"golang.org/x/exp/maps"
"golang.org/x/exp/slices"
batchv1 "k8s.io/api/batch/v1" batchv1 "k8s.io/api/batch/v1"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1" policyv1 "k8s.io/api/policy/v1"

View File

@ -2,15 +2,14 @@ package cluster
import ( import (
"bytes" "bytes"
"context"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"slices"
"testing" "testing"
"time" "time"
"context"
"golang.org/x/exp/slices"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"

View File

@ -9,6 +9,6 @@ jq==1.7.0
json_delta>=2.0.2 json_delta>=2.0.2
kubernetes==11.0.0 kubernetes==11.0.0
python-json-logger==2.0.7 python-json-logger==2.0.7
requests==2.32.2 requests==2.32.4
stups-tokens>=1.1.19 stups-tokens>=1.1.19
werkzeug==3.0.6 werkzeug==3.0.6