Skip to content

Commit b741d14

Browse files
Merge branch 'master' of https://github.com/CrunchyData/postgres-operator into ISSUE-3435/appProtocol
2 parents 1953906 + bf300c7 commit b741d14

File tree

11 files changed

+136
-8
lines changed

11 files changed

+136
-8
lines changed

config/crd/bases/postgres-operator.crunchydata.com_postgresclusters.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10267,7 +10267,7 @@ spec:
1026710267
postgresVersion:
1026810268
description: The major version of PostgreSQL installed in the PostgreSQL
1026910269
image
10270-
maximum: 14
10270+
maximum: 15
1027110271
minimum: 10
1027210272
type: integer
1027310273
proxy:

docs/content/tutorial/backups.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,19 @@ The full list of [pgBackRest configuration options](https://pgbackrest.org/confi
379379

380380
[https://pgbackrest.org/configuration.html](https://pgbackrest.org/configuration.html)
381381

382+
## IPv6 Support
383+
384+
If you are running your cluster in an IPv6-only environment, you will need to add an annotation to your PostgresCluster so that PGO knows to set pgBackRest's `tls-server-address` to an IPv6 address. Otherwise, `tls-server-address` will be set to `0.0.0.0`, making pgBackRest inaccessible, and backups will not run. The annotation should be added as shown below:
385+
386+
```yaml
387+
apiVersion: postgres-operator.crunchydata.com/v1beta1
388+
kind: PostgresCluster
389+
metadata:
390+
name: hippo
391+
annotations:
392+
postgres-operator.crunchydata.com/pgbackrest-ip-version: IPv6
393+
```
394+
382395
## Next Steps
383396

384397
We've now seen how to use PGO to get our backups and archives set up and safely stored. Now let's take a look at [backup management]({{< relref "./backup-management.md" >}}) and how we can do things such as set backup frequency, set retention policies, and even take one-off backups!

internal/controller/postgrescluster/pgbackrest.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,7 +1011,9 @@ func (r *Reconciler) reconcileRestoreJob(ctx context.Context,
10111011
for _, opt := range options {
10121012
var msg string
10131013
switch {
1014-
case strings.Contains(opt, "--repo"):
1014+
// Since '--repo' can be set with or without an equals ('=') sign, we check for both
1015+
// usage patterns.
1016+
case strings.Contains(opt, "--repo=") || strings.Contains(opt, "--repo "):
10151017
msg = "Option '--repo' is not allowed: please use the 'repoName' field instead."
10161018
case strings.Contains(opt, "--stanza"):
10171019
msg = "Option '--stanza' is not allowed: the operator will automatically set this " +
@@ -2200,9 +2202,11 @@ func (r *Reconciler) reconcileManualBackup(ctx context.Context,
22002202
// and not using the "--repo" option in the "manual.options" field. Therefore, record a
22012203
// warning event and return if a "--repo" option is found. Reconciliation will then be
22022204
// reattempted when "--repo" is removed from "manual.options" and the spec is updated.
2205+
// Since '--repo' can be set with or without an equals ('=') sign, we check for both
2206+
// usage patterns.
22032207
backupOpts := postgresCluster.Spec.Backups.PGBackRest.Manual.Options
22042208
for _, opt := range backupOpts {
2205-
if strings.Contains(opt, "--repo") {
2209+
if strings.Contains(opt, "--repo=") || strings.Contains(opt, "--repo ") {
22062210
r.Recorder.Eventf(postgresCluster, corev1.EventTypeWarning, "InvalidManualBackup",
22072211
"Option '--repo' is not allowed: please use the 'repoName' field instead.",
22082212
repoName)

internal/controller/postgrescluster/pgbackrest_test.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1831,13 +1831,27 @@ func TestReconcilePostgresClusterDataSource(t *testing.T) {
18311831
expectedClusterCondition: nil,
18321832
},
18331833
}, {
1834-
desc: "invalid option: repo",
1834+
desc: "invalid option: --repo=",
18351835
dataSource: &v1beta1.DataSource{PostgresCluster: &v1beta1.PostgresClusterDataSource{
1836-
ClusterName: "invalid-repo-option", RepoName: "repo1",
1837-
Options: []string{"--repo"},
1836+
ClusterName: "invalid-repo-option-equals", RepoName: "repo1",
1837+
Options: []string{"--repo="},
18381838
}},
18391839
clusterBootstrapped: false,
1840-
sourceClusterName: "invalid-repo-option",
1840+
sourceClusterName: "invalid-repo-option-equals",
1841+
sourceClusterRepos: []v1beta1.PGBackRestRepo{{Name: "repo1"}},
1842+
result: testResult{
1843+
configCount: 1, jobCount: 0, pvcCount: 1,
1844+
invalidSourceRepo: false, invalidSourceCluster: false, invalidOptions: true,
1845+
expectedClusterCondition: nil,
1846+
},
1847+
}, {
1848+
desc: "invalid option: --repo ",
1849+
dataSource: &v1beta1.DataSource{PostgresCluster: &v1beta1.PostgresClusterDataSource{
1850+
ClusterName: "invalid-repo-option-space", RepoName: "repo1",
1851+
Options: []string{"--repo "},
1852+
}},
1853+
clusterBootstrapped: false,
1854+
sourceClusterName: "invalid-repo-option-space",
18411855
sourceClusterRepos: []v1beta1.PGBackRestRepo{{Name: "repo1"}},
18421856
result: testResult{
18431857
configCount: 1, jobCount: 0, pvcCount: 1,

internal/naming/annotations.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,12 @@ const (
5050
// timestamp), which will be stored in the PostgresCluster status to properly track completion
5151
// of the Job.
5252
PGBackRestRestore = annotationPrefix + "pgbackrest-restore"
53+
54+
// PGBackRestIPVersion is an annotation used to indicate whether an IPv6 wildcard address should be
55+
// used for the pgBackRest "tls-server-address" or not. If the user wants to use IPv6, the value
56+
// should be "IPv6". As of right now, if the annotation is not present or if the annotation's value
57+
// is anything other than "IPv6", the "tls-server-address" will default to IPv4 (0.0.0.0). The need
58+
// for this annotation is due to an issue in pgBackRest (#1841) where using a wildcard address to
59+
// bind all addresses does not work in certain IPv6 environments.
60+
PGBackRestIPVersion = annotationPrefix + "pgbackrest-ip-version"
5361
)

internal/naming/annotations_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,5 @@ func TestAnnotationsValid(t *testing.T) {
2929
assert.Assert(t, nil == validation.IsQualifiedName(PGBackRestConfigHash))
3030
assert.Assert(t, nil == validation.IsQualifiedName(PGBackRestCurrentConfig))
3131
assert.Assert(t, nil == validation.IsQualifiedName(PGBackRestRestore))
32+
assert.Assert(t, nil == validation.IsQualifiedName(PGBackRestIPVersion))
3233
}

internal/pgbackrest/config.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package pgbackrest
1818
import (
1919
"context"
2020
"fmt"
21+
"strings"
2122

2223
corev1 "k8s.io/api/core/v1"
2324
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -465,6 +466,16 @@ func serverConfig(cluster *v1beta1.PostgresCluster) iniSectionSet {
465466
// - https://releases.k8s.io/v1.23.0/pkg/kubelet/kubelet_pods.go#L345
466467
global.Set("tls-server-address", "0.0.0.0")
467468

469+
// NOTE (dsessler7): As pointed out by Chris above, there is an issue in
470+
// pgBackRest (#1841), where using a wildcard address to bind all addresses
471+
// does not work in certain IPv6 environments. Until this is fixed, we are
472+
// going to workaround the issue by allowing the user to add an annotation to
473+
// enable IPv6. We will check for that annotation here and override the
474+
// "tls-server-address" setting accordingly.
475+
if strings.EqualFold(cluster.Annotations[naming.PGBackRestIPVersion], "ipv6") {
476+
global.Set("tls-server-address", "::")
477+
}
478+
468479
// The client certificate for this cluster is allowed to connect for any stanza.
469480
// Without the wildcard "*", the "pgbackrest info" and "pgbackrest repo-ls"
470481
// commands fail with "access denied" when invoked without a "--stanza" flag.

internal/pgbackrest/config_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,3 +337,26 @@ log-level-stderr = error
337337
log-timestamp = n
338338
`)
339339
}
340+
341+
func TestServerConfigIPv6(t *testing.T) {
342+
cluster := &v1beta1.PostgresCluster{}
343+
cluster.UID = "shoe"
344+
cluster.Annotations = map[string]string{
345+
naming.PGBackRestIPVersion: "IPv6",
346+
}
347+
348+
assert.Equal(t, serverConfig(cluster).String(), `
349+
[global]
350+
tls-server-address = ::
351+
tls-server-auth = pgbackrest@shoe=*
352+
tls-server-ca-file = /etc/pgbackrest/conf.d/~postgres-operator/tls-ca.crt
353+
tls-server-cert-file = /etc/pgbackrest/server/server-tls.crt
354+
tls-server-key-file = /etc/pgbackrest/server/server-tls.key
355+
356+
[global:server]
357+
log-level-console = detail
358+
log-level-file = off
359+
log-level-stderr = error
360+
log-timestamp = n
361+
`)
362+
}

internal/pgbackrest/iana.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
Copyright 2021 - 2022 Crunchy Data Solutions, Inc.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
*/
15+
16+
package pgbackrest
17+
18+
// The protocol used by pgBackRest is registered with the Internet Assigned
19+
// Numbers Authority (IANA).
20+
// - https://www.iana.org/assignments/service-names-port-numbers
21+
const (
22+
// IANAPortNumber is the port assigned to pgBackRest at the IANA.
23+
IANAPortNumber = 8432
24+
25+
// IANAServiceName is the name of the pgBackRest protocol at the IANA.
26+
IANAServiceName = "pgbackrest"
27+
)

internal/postgres/iana.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
Copyright 2021 - 2022 Crunchy Data Solutions, Inc.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
*/
15+
16+
package postgres
17+
18+
// The protocol used by PostgreSQL is registered with the Internet Assigned
19+
// Numbers Authority (IANA).
20+
// - https://www.iana.org/assignments/service-names-port-numbers
21+
const (
22+
// IANAPortNumber is the port assigned to PostgreSQL at the IANA.
23+
IANAPortNumber = 5432
24+
25+
// IANAServiceName is the name of the PostgreSQL protocol at the IANA.
26+
IANAServiceName = "postgresql"
27+
)

pkg/apis/postgres-operator.crunchydata.com/v1beta1/postgrescluster_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ type PostgresClusterSpec struct {
123123
// The major version of PostgreSQL installed in the PostgreSQL image
124124
// +kubebuilder:validation:Required
125125
// +kubebuilder:validation:Minimum=10
126-
// +kubebuilder:validation:Maximum=14
126+
// +kubebuilder:validation:Maximum=15
127127
// +operator-sdk:csv:customresourcedefinitions:type=spec,order=1
128128
PostgresVersion int `json:"postgresVersion"`
129129

0 commit comments

Comments
 (0)