diff --git a/charts/postgres-operator/crds/postgresqls.yaml b/charts/postgres-operator/crds/postgresqls.yaml index 9d56a6ee3..6f938cf8f 100644 --- a/charts/postgres-operator/crds/postgresqls.yaml +++ b/charts/postgres-operator/crds/postgresqls.yaml @@ -223,6 +223,10 @@ spec: items: type: string pattern: '^\ *((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\d):([0-5]?\d)|(2[0-3]|[01]?\d):([0-5]?\d))-((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\d):([0-5]?\d)|(2[0-3]|[01]?\d):([0-5]?\d))\ *$' + masterServiceAnnotations: + type: object + additionalProperties: + type: string nodeAffinity: type: object properties: @@ -402,6 +406,10 @@ spec: replicaLoadBalancer: type: boolean description: deprecated + replicaServiceAnnotations: + type: object + additionalProperties: + type: string resources: type: object properties: diff --git a/docs/administrator.md b/docs/administrator.md index 5e1ade60c..19cfe2109 100644 --- a/docs/administrator.md +++ b/docs/administrator.md @@ -784,9 +784,15 @@ services: This value can't be overwritten. If any changing in its value is needed, it MUST be done changing the DNS format operator config parameters; and - `service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout` with - a default value of "3600". This value can be overwritten with the operator - config parameter `custom_service_annotations` or the cluster parameter - `serviceAnnotations`. + a default value of "3600". + +There are multiple options to specify service annotations that will be merged +with each other and override in the following order (where latter take +precedence): +1. Default annotations if LoadBalancer is enabled +2. Globally configured `custom_service_annotations` +3. `serviceAnnotations` specified in the cluster manifest +4. `masterServiceAnnotations` and `replicaServiceAnnotations` specified in the cluster manifest To limit the range of IP addresses that can reach a load balancer, specify the desired ranges in the `allowedSourceRanges` field (applies to both master and diff --git a/docs/reference/cluster_manifest.md b/docs/reference/cluster_manifest.md index 9e5789d59..8cca890c8 100644 --- a/docs/reference/cluster_manifest.md +++ b/docs/reference/cluster_manifest.md @@ -173,6 +173,22 @@ These parameters are grouped directly under the `spec` key in the manifest. [administrator docs](https://github.com/zalando/postgres-operator/blob/master/docs/administrator.md#load-balancers-and-allowed-ip-ranges) for more information regarding default values and overwrite rules. +* **masterServiceAnnotations** + A map of key value pairs that gets attached as [annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) + to the master service created for the database cluster. Check the + [administrator docs](https://github.com/zalando/postgres-operator/blob/master/docs/administrator.md#load-balancers-and-allowed-ip-ranges) + for more information regarding default values and overwrite rules. + This field overrides `serviceAnnotations` with the same key for the master + service if not empty. + +* **replicaServiceAnnotations** + A map of key value pairs that gets attached as [annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) + to the replica service created for the database cluster. Check the + [administrator docs](https://github.com/zalando/postgres-operator/blob/master/docs/administrator.md#load-balancers-and-allowed-ip-ranges) + for more information regarding default values and overwrite rules. + This field overrides `serviceAnnotations` with the same key for the replica + service if not empty. + * **enableShmVolume** Start a database pod without limitations on shm memory. By default Docker limit `/dev/shm` to `64M` (see e.g. the [docker diff --git a/go.mod b/go.mod index 2d20a7619..39c76a9c5 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,8 @@ require ( github.com/r3labs/diff v1.1.0 github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 - golang.org/x/crypto v0.0.0-20211202192323-5770296d904e + golang.org/x/crypto v0.1.0 + golang.org/x/exp v0.0.0-20230108222341-4b8118a2686a gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.23.5 k8s.io/apiextensions-apiserver v0.23.5 @@ -33,7 +34,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.5 // indirect + github.com/google/go-cmp v0.5.8 // indirect github.com/google/gofuzz v1.1.0 // indirect github.com/googleapis/gnostic v0.5.5 // indirect github.com/imdario/mergo v0.3.5 // indirect @@ -47,15 +48,14 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - golang.org/x/mod v0.5.1 // indirect - golang.org/x/net v0.0.0-20211209124913-491a49abca63 // indirect + golang.org/x/mod v0.6.0 // indirect + golang.org/x/net v0.1.0 // indirect golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect - golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect - golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect - golang.org/x/text v0.3.7 // indirect + golang.org/x/sys v0.1.0 // indirect + golang.org/x/term v0.1.0 // indirect + golang.org/x/text v0.4.0 // indirect golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect - golang.org/x/tools v0.1.7 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + golang.org/x/tools v0.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.27.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/go.sum b/go.sum index 7cb962923..385d31cdb 100644 --- a/go.sum +++ b/go.sum @@ -216,8 +216,9 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -500,8 +501,8 @@ 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-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211202192323-5770296d904e h1:MUP6MR3rJ7Gk9LEia0LP2ytiH6MuCfs7qYz+47jGdD8= -golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -512,6 +513,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20230108222341-4b8118a2686a h1:tlXy25amD5A7gOfbXdqCGN5k8ESEed/Ee1E5RcrYnqU= +golang.org/x/exp v0.0.0-20230108222341-4b8118a2686a/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -537,8 +540,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -586,8 +589,9 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -676,11 +680,12 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 h1:TyHqChC80pFkXWraUUf6RuB5IqFdQieMLwwCJokV2pc= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -689,8 +694,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -756,8 +762,8 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM= -golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ= -golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/manifests/postgresql.crd.yaml b/manifests/postgresql.crd.yaml index b2178a246..6066abad1 100644 --- a/manifests/postgresql.crd.yaml +++ b/manifests/postgresql.crd.yaml @@ -221,6 +221,10 @@ spec: items: type: string pattern: '^\ *((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\d):([0-5]?\d)|(2[0-3]|[01]?\d):([0-5]?\d))-((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\d):([0-5]?\d)|(2[0-3]|[01]?\d):([0-5]?\d))\ *$' + masterServiceAnnotations: + type: object + additionalProperties: + type: string nodeAffinity: type: object properties: @@ -400,6 +404,10 @@ spec: replicaLoadBalancer: type: boolean description: deprecated + replicaServiceAnnotations: + type: object + additionalProperties: + type: string resources: type: object properties: diff --git a/pkg/apis/acid.zalan.do/v1/crds.go b/pkg/apis/acid.zalan.do/v1/crds.go index 22d82a201..4a08ec2f4 100644 --- a/pkg/apis/acid.zalan.do/v1/crds.go +++ b/pkg/apis/acid.zalan.do/v1/crds.go @@ -355,6 +355,14 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{ }, }, }, + "masterServiceAnnotations": { + Type: "object", + AdditionalProperties: &apiextv1.JSONSchemaPropsOrBool{ + Schema: &apiextv1.JSONSchemaProps{ + Type: "string", + }, + }, + }, "nodeAffinity": { Type: "object", Properties: map[string]apiextv1.JSONSchemaProps{ @@ -654,6 +662,14 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{ Type: "boolean", Description: "deprecated", }, + "replicaServiceAnnotations": { + Type: "object", + AdditionalProperties: &apiextv1.JSONSchemaPropsOrBool{ + Schema: &apiextv1.JSONSchemaProps{ + Type: "string", + }, + }, + }, "resources": { Type: "object", Properties: map[string]apiextv1.JSONSchemaProps{ diff --git a/pkg/apis/acid.zalan.do/v1/postgresql_type.go b/pkg/apis/acid.zalan.do/v1/postgresql_type.go index 19e2f685f..67007b522 100644 --- a/pkg/apis/acid.zalan.do/v1/postgresql_type.go +++ b/pkg/apis/acid.zalan.do/v1/postgresql_type.go @@ -79,10 +79,14 @@ type PostgresSpec struct { StandbyCluster *StandbyDescription `json:"standby,omitempty"` PodAnnotations map[string]string `json:"podAnnotations,omitempty"` ServiceAnnotations map[string]string `json:"serviceAnnotations,omitempty"` - TLS *TLSDescription `json:"tls,omitempty"` - AdditionalVolumes []AdditionalVolume `json:"additionalVolumes,omitempty"` - Streams []Stream `json:"streams,omitempty"` - Env []v1.EnvVar `json:"env,omitempty"` + // MasterServiceAnnotations takes precedence over ServiceAnnotations for master role if not empty + MasterServiceAnnotations map[string]string `json:"masterServiceAnnotations,omitempty"` + // ReplicaServiceAnnotations takes precedence over ServiceAnnotations for replica role if not empty + ReplicaServiceAnnotations map[string]string `json:"replicaServiceAnnotations,omitempty"` + TLS *TLSDescription `json:"tls,omitempty"` + AdditionalVolumes []AdditionalVolume `json:"additionalVolumes,omitempty"` + Streams []Stream `json:"streams,omitempty"` + Env []v1.EnvVar `json:"env,omitempty"` // deprecated json tags InitContainersOld []v1.Container `json:"init_containers,omitempty"` diff --git a/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go b/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go index 9d9a185bd..a43c995c5 100644 --- a/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go +++ b/pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go @@ -792,6 +792,20 @@ func (in *PostgresSpec) DeepCopyInto(out *PostgresSpec) { (*out)[key] = val } } + if in.MasterServiceAnnotations != nil { + in, out := &in.MasterServiceAnnotations, &out.MasterServiceAnnotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.ReplicaServiceAnnotations != nil { + in, out := &in.ReplicaServiceAnnotations, &out.ReplicaServiceAnnotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } if in.TLS != nil { in, out := &in.TLS, &out.TLS *out = new(TLSDescription) diff --git a/pkg/cluster/cluster_test.go b/pkg/cluster/cluster_test.go index 24994cfc7..b9633d903 100644 --- a/pkg/cluster/cluster_test.go +++ b/pkg/cluster/cluster_test.go @@ -524,7 +524,9 @@ func TestServiceAnnotations(t *testing.T) { enableReplicaLoadBalancerOC bool enableTeamIdClusterPrefix bool operatorAnnotations map[string]string - clusterAnnotations map[string]string + serviceAnnotations map[string]string + masterServiceAnnotations map[string]string + replicaServiceAnnotations map[string]string expect map[string]string }{ //MASTER @@ -535,7 +537,7 @@ func TestServiceAnnotations(t *testing.T) { enableMasterLoadBalancerOC: false, enableTeamIdClusterPrefix: false, operatorAnnotations: make(map[string]string), - clusterAnnotations: make(map[string]string), + serviceAnnotations: make(map[string]string), expect: make(map[string]string), }, { @@ -545,7 +547,7 @@ func TestServiceAnnotations(t *testing.T) { enableMasterLoadBalancerOC: false, enableTeamIdClusterPrefix: false, operatorAnnotations: make(map[string]string), - clusterAnnotations: make(map[string]string), + serviceAnnotations: make(map[string]string), expect: map[string]string{ "external-dns.alpha.kubernetes.io/hostname": "acid-test.test.db.example.com,test.acid.db.example.com", "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "3600", @@ -558,7 +560,7 @@ func TestServiceAnnotations(t *testing.T) { enableMasterLoadBalancerOC: true, enableTeamIdClusterPrefix: false, operatorAnnotations: make(map[string]string), - clusterAnnotations: make(map[string]string), + serviceAnnotations: make(map[string]string), expect: make(map[string]string), }, { @@ -567,7 +569,7 @@ func TestServiceAnnotations(t *testing.T) { enableMasterLoadBalancerOC: true, enableTeamIdClusterPrefix: false, operatorAnnotations: make(map[string]string), - clusterAnnotations: make(map[string]string), + serviceAnnotations: make(map[string]string), expect: map[string]string{ "external-dns.alpha.kubernetes.io/hostname": "acid-test.test.db.example.com,test.acid.db.example.com", "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "3600", @@ -579,7 +581,7 @@ func TestServiceAnnotations(t *testing.T) { enableMasterLoadBalancerOC: true, enableTeamIdClusterPrefix: false, operatorAnnotations: make(map[string]string), - clusterAnnotations: map[string]string{"foo": "bar"}, + serviceAnnotations: map[string]string{"foo": "bar"}, expect: map[string]string{ "external-dns.alpha.kubernetes.io/hostname": "acid-test.test.db.example.com,test.acid.db.example.com", "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "3600", @@ -593,7 +595,7 @@ func TestServiceAnnotations(t *testing.T) { enableMasterLoadBalancerOC: true, enableTeamIdClusterPrefix: false, operatorAnnotations: make(map[string]string), - clusterAnnotations: map[string]string{"foo": "bar"}, + serviceAnnotations: map[string]string{"foo": "bar"}, expect: map[string]string{"foo": "bar"}, }, { @@ -602,7 +604,7 @@ func TestServiceAnnotations(t *testing.T) { enableMasterLoadBalancerOC: true, enableTeamIdClusterPrefix: false, operatorAnnotations: map[string]string{"foo": "bar"}, - clusterAnnotations: make(map[string]string), + serviceAnnotations: make(map[string]string), expect: map[string]string{ "external-dns.alpha.kubernetes.io/hostname": "acid-test.test.db.example.com,test.acid.db.example.com", "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "3600", @@ -617,7 +619,7 @@ func TestServiceAnnotations(t *testing.T) { operatorAnnotations: map[string]string{ "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "1800", }, - clusterAnnotations: make(map[string]string), + serviceAnnotations: make(map[string]string), expect: map[string]string{ "external-dns.alpha.kubernetes.io/hostname": "acid-test.test.db.example.com,test.acid.db.example.com", "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "1800", @@ -629,7 +631,7 @@ func TestServiceAnnotations(t *testing.T) { enableMasterLoadBalancerOC: true, enableTeamIdClusterPrefix: false, operatorAnnotations: make(map[string]string), - clusterAnnotations: map[string]string{ + serviceAnnotations: map[string]string{ "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "1800", }, expect: map[string]string{ @@ -643,7 +645,7 @@ func TestServiceAnnotations(t *testing.T) { enableMasterLoadBalancerOC: true, enableTeamIdClusterPrefix: false, operatorAnnotations: make(map[string]string), - clusterAnnotations: map[string]string{ + serviceAnnotations: map[string]string{ "external-dns.alpha.kubernetes.io/hostname": "wrong.external-dns-name.example.com", }, expect: map[string]string{ @@ -656,13 +658,32 @@ func TestServiceAnnotations(t *testing.T) { role: "master", enableMasterLoadBalancerOC: true, enableTeamIdClusterPrefix: true, - clusterAnnotations: make(map[string]string), + serviceAnnotations: make(map[string]string), operatorAnnotations: make(map[string]string), expect: map[string]string{ "external-dns.alpha.kubernetes.io/hostname": "acid-test.test.db.example.com,test.acid.db.example.com", "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "3600", }, }, + { + about: "Master with master service annotations override service annotations", + role: "master", + enableMasterLoadBalancerOC: true, + enableTeamIdClusterPrefix: false, + operatorAnnotations: make(map[string]string), + serviceAnnotations: map[string]string{ + "service.beta.kubernetes.io/aws-load-balancer-nlb-target-type": "ip", + "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "1800", + }, + masterServiceAnnotations: map[string]string{ + "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "2000", + }, + expect: map[string]string{ + "external-dns.alpha.kubernetes.io/hostname": "acid-test.test.db.example.com,test.acid.db.example.com", + "service.beta.kubernetes.io/aws-load-balancer-nlb-target-type": "ip", + "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "2000", + }, + }, // REPLICA { about: "Replica with no annotations and EnableReplicaLoadBalancer disabled on spec and OperatorConfig", @@ -671,7 +692,7 @@ func TestServiceAnnotations(t *testing.T) { enableReplicaLoadBalancerOC: false, enableTeamIdClusterPrefix: false, operatorAnnotations: make(map[string]string), - clusterAnnotations: make(map[string]string), + serviceAnnotations: make(map[string]string), expect: make(map[string]string), }, { @@ -681,7 +702,7 @@ func TestServiceAnnotations(t *testing.T) { enableReplicaLoadBalancerOC: false, enableTeamIdClusterPrefix: false, operatorAnnotations: make(map[string]string), - clusterAnnotations: make(map[string]string), + serviceAnnotations: make(map[string]string), expect: map[string]string{ "external-dns.alpha.kubernetes.io/hostname": "acid-test-repl.test.db.example.com,test-repl.acid.db.example.com", "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "3600", @@ -694,7 +715,7 @@ func TestServiceAnnotations(t *testing.T) { enableReplicaLoadBalancerOC: true, enableTeamIdClusterPrefix: false, operatorAnnotations: make(map[string]string), - clusterAnnotations: make(map[string]string), + serviceAnnotations: make(map[string]string), expect: make(map[string]string), }, { @@ -703,7 +724,7 @@ func TestServiceAnnotations(t *testing.T) { enableReplicaLoadBalancerOC: true, enableTeamIdClusterPrefix: false, operatorAnnotations: make(map[string]string), - clusterAnnotations: make(map[string]string), + serviceAnnotations: make(map[string]string), expect: map[string]string{ "external-dns.alpha.kubernetes.io/hostname": "acid-test-repl.test.db.example.com,test-repl.acid.db.example.com", "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "3600", @@ -715,7 +736,7 @@ func TestServiceAnnotations(t *testing.T) { enableReplicaLoadBalancerOC: true, enableTeamIdClusterPrefix: false, operatorAnnotations: make(map[string]string), - clusterAnnotations: map[string]string{"foo": "bar"}, + serviceAnnotations: map[string]string{"foo": "bar"}, expect: map[string]string{ "external-dns.alpha.kubernetes.io/hostname": "acid-test-repl.test.db.example.com,test-repl.acid.db.example.com", "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "3600", @@ -729,7 +750,7 @@ func TestServiceAnnotations(t *testing.T) { enableReplicaLoadBalancerOC: true, enableTeamIdClusterPrefix: false, operatorAnnotations: make(map[string]string), - clusterAnnotations: map[string]string{"foo": "bar"}, + serviceAnnotations: map[string]string{"foo": "bar"}, expect: map[string]string{"foo": "bar"}, }, { @@ -738,7 +759,7 @@ func TestServiceAnnotations(t *testing.T) { enableReplicaLoadBalancerOC: true, enableTeamIdClusterPrefix: false, operatorAnnotations: map[string]string{"foo": "bar"}, - clusterAnnotations: make(map[string]string), + serviceAnnotations: make(map[string]string), expect: map[string]string{ "external-dns.alpha.kubernetes.io/hostname": "acid-test-repl.test.db.example.com,test-repl.acid.db.example.com", "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "3600", @@ -753,7 +774,7 @@ func TestServiceAnnotations(t *testing.T) { operatorAnnotations: map[string]string{ "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "1800", }, - clusterAnnotations: make(map[string]string), + serviceAnnotations: make(map[string]string), expect: map[string]string{ "external-dns.alpha.kubernetes.io/hostname": "acid-test-repl.test.db.example.com,test-repl.acid.db.example.com", "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "1800", @@ -765,7 +786,7 @@ func TestServiceAnnotations(t *testing.T) { enableReplicaLoadBalancerOC: true, enableTeamIdClusterPrefix: false, operatorAnnotations: make(map[string]string), - clusterAnnotations: map[string]string{ + serviceAnnotations: map[string]string{ "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "1800", }, expect: map[string]string{ @@ -779,7 +800,7 @@ func TestServiceAnnotations(t *testing.T) { enableReplicaLoadBalancerOC: true, enableTeamIdClusterPrefix: false, operatorAnnotations: make(map[string]string), - clusterAnnotations: map[string]string{ + serviceAnnotations: map[string]string{ "external-dns.alpha.kubernetes.io/hostname": "wrong.external-dns-name.example.com", }, expect: map[string]string{ @@ -792,13 +813,32 @@ func TestServiceAnnotations(t *testing.T) { role: "replica", enableReplicaLoadBalancerOC: true, enableTeamIdClusterPrefix: true, - clusterAnnotations: make(map[string]string), + serviceAnnotations: make(map[string]string), operatorAnnotations: make(map[string]string), expect: map[string]string{ "external-dns.alpha.kubernetes.io/hostname": "acid-test-repl.test.db.example.com,test-repl.acid.db.example.com", "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "3600", }, }, + { + about: "Replica with replica service annotations override service annotations", + role: "replica", + enableReplicaLoadBalancerOC: true, + enableTeamIdClusterPrefix: false, + operatorAnnotations: make(map[string]string), + serviceAnnotations: map[string]string{ + "service.beta.kubernetes.io/aws-load-balancer-nlb-target-type": "ip", + "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "1800", + }, + replicaServiceAnnotations: map[string]string{ + "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "2000", + }, + expect: map[string]string{ + "external-dns.alpha.kubernetes.io/hostname": "acid-test-repl.test.db.example.com,test-repl.acid.db.example.com", + "service.beta.kubernetes.io/aws-load-balancer-nlb-target-type": "ip", + "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout": "2000", + }, + }, // COMMON { about: "cluster annotations append to operator annotations", @@ -806,7 +846,7 @@ func TestServiceAnnotations(t *testing.T) { enableReplicaLoadBalancerOC: false, enableTeamIdClusterPrefix: false, operatorAnnotations: map[string]string{"foo": "bar"}, - clusterAnnotations: map[string]string{"post": "gres"}, + serviceAnnotations: map[string]string{"post": "gres"}, expect: map[string]string{"foo": "bar", "post": "gres"}, }, { @@ -815,7 +855,7 @@ func TestServiceAnnotations(t *testing.T) { enableReplicaLoadBalancerOC: false, enableTeamIdClusterPrefix: false, operatorAnnotations: map[string]string{"foo": "bar", "post": "gres"}, - clusterAnnotations: map[string]string{"post": "greSQL"}, + serviceAnnotations: map[string]string{"post": "greSQL"}, expect: map[string]string{"foo": "bar", "post": "greSQL"}, }, } @@ -833,7 +873,9 @@ func TestServiceAnnotations(t *testing.T) { cl.Postgresql.Spec.ClusterName = "" cl.Postgresql.Spec.TeamID = "acid" - cl.Postgresql.Spec.ServiceAnnotations = tt.clusterAnnotations + cl.Postgresql.Spec.ServiceAnnotations = tt.serviceAnnotations + cl.Postgresql.Spec.MasterServiceAnnotations = tt.masterServiceAnnotations + cl.Postgresql.Spec.ReplicaServiceAnnotations = tt.replicaServiceAnnotations cl.Postgresql.Spec.EnableMasterLoadBalancer = tt.enableMasterLoadBalancerSpec cl.Postgresql.Spec.EnableReplicaLoadBalancer = tt.enableReplicaLoadBalancerSpec diff --git a/pkg/cluster/k8sres.go b/pkg/cluster/k8sres.go index 4ef61f8b9..2e317c1a2 100644 --- a/pkg/cluster/k8sres.go +++ b/pkg/cluster/k8sres.go @@ -28,6 +28,7 @@ import ( "github.com/zalando/postgres-operator/pkg/util/k8sutil" "github.com/zalando/postgres-operator/pkg/util/patroni" "github.com/zalando/postgres-operator/pkg/util/retryutil" + "golang.org/x/exp/maps" batchv1 "k8s.io/api/batch/v1" "k8s.io/apimachinery/pkg/labels" ) @@ -1901,13 +1902,16 @@ func (c *Cluster) configureLoadBalanceService(serviceSpec *v1.ServiceSpec, sourc func (c *Cluster) generateServiceAnnotations(role PostgresRole, spec *acidv1.PostgresSpec) map[string]string { annotations := make(map[string]string) + maps.Copy(annotations, c.OpConfig.CustomServiceAnnotations) - for k, v := range c.OpConfig.CustomServiceAnnotations { - annotations[k] = v - } - if spec != nil || spec.ServiceAnnotations != nil { - for k, v := range spec.ServiceAnnotations { - annotations[k] = v + if spec != nil { + maps.Copy(annotations, spec.ServiceAnnotations) + + switch role { + case Master: + maps.Copy(annotations, spec.MasterServiceAnnotations) + case Replica: + maps.Copy(annotations, spec.ReplicaServiceAnnotations) } }