Skip to content

Commit b17d8f3

Browse files
committed
Create warning event when postgres version is EOL.
1 parent 561c650 commit b17d8f3

File tree

4 files changed

+120
-0
lines changed

4 files changed

+120
-0
lines changed

internal/controller/postgrescluster/controller.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ func (r *Reconciler) Reconcile(
136136
return runtime.ErrorWithBackoff(err)
137137
}
138138
}
139+
// Issue Warning Event if postgres version is EOL according to PostgreSQL:
140+
// https://www.postgresql.org/support/versioning/
141+
currentTime := time.Now()
142+
if postgres.ReleaseIsFinal(cluster.Spec.PostgresVersion, currentTime) {
143+
r.Recorder.Eventf(cluster, corev1.EventTypeWarning, "EndOfLifePostgresVersion",
144+
"Postgres Version %v is End-Of-Life. We recommend upgrading to the latest supported version.",
145+
cluster.Spec.PostgresVersion)
146+
}
139147

140148
if cluster.Spec.Standby != nil &&
141149
cluster.Spec.Standby.Enabled &&

internal/controller/postgrescluster/controller_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,4 +556,66 @@ spec:
556556
Expect(instance.Spec.Replicas).To(PointTo(BeEquivalentTo(1)))
557557
})
558558
})
559+
560+
Context("Postgres version EOL", func() {
561+
var cluster *v1beta1.PostgresCluster
562+
563+
BeforeEach(func() {
564+
cluster = create(`
565+
metadata:
566+
name: old-postgres
567+
spec:
568+
postgresVersion: 11
569+
image: postgres
570+
instances:
571+
- name: instance1
572+
dataVolumeClaimSpec:
573+
accessModes:
574+
- "ReadWriteMany"
575+
resources:
576+
requests:
577+
storage: 1Gi
578+
backups:
579+
pgbackrest:
580+
image: pgbackrest
581+
repos:
582+
- name: repo1
583+
volume:
584+
volumeClaimSpec:
585+
accessModes:
586+
- "ReadWriteOnce"
587+
resources:
588+
requests:
589+
storage: 1Gi
590+
`)
591+
Expect(reconcile(cluster)).To(BeZero())
592+
})
593+
594+
AfterEach(func() {
595+
ctx := context.Background()
596+
597+
if cluster != nil {
598+
Expect(client.IgnoreNotFound(
599+
suite.Client.Delete(ctx, cluster),
600+
)).To(Succeed())
601+
602+
// Remove finalizers, if any, so the namespace can terminate.
603+
Expect(client.IgnoreNotFound(
604+
suite.Client.Patch(ctx, cluster, client.RawPatch(
605+
client.Merge.Type(), []byte(`{"metadata":{"finalizers":[]}}`))),
606+
)).To(Succeed())
607+
}
608+
})
609+
610+
Specify("Postgres EOL Warning Event", func() {
611+
existing := &v1beta1.PostgresCluster{}
612+
Expect(suite.Client.Get(
613+
context.Background(), client.ObjectKeyFromObject(cluster), existing,
614+
)).To(Succeed())
615+
616+
event, ok := <-test.Recorder.Events
617+
Expect(ok).To(BeTrue())
618+
Expect(event).To(ContainSubstring("End-Of-Life."))
619+
})
620+
})
559621
})

internal/postgres/config.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"context"
99
"fmt"
1010
"strings"
11+
"time"
1112

1213
corev1 "k8s.io/api/core/v1"
1314

@@ -425,3 +426,29 @@ chmod +x /tmp/pg_rewind_tde.sh
425426

426427
return append([]string{"bash", "-ceu", "--", script, "startup"}, args...)
427428
}
429+
430+
// ReleaseIsFinal returns whether or not t is definitively past the final
431+
// scheduled release of a Postgres version.
432+
// See: https://www.postgresql.org/support/versioning/
433+
func ReleaseIsFinal(majorVersion int, t time.Time) bool {
434+
switch majorVersion {
435+
case 10:
436+
return t.After(time.Date(2022, time.November+1, 10, 0, 0, 0, 0, time.UTC))
437+
case 11:
438+
return t.After(time.Date(2023, time.November+1, +9, 0, 0, 0, 0, time.UTC))
439+
case 12:
440+
return t.After(time.Date(2024, time.November+1, 14, 0, 0, 0, 0, time.UTC))
441+
case 13:
442+
return t.After(time.Date(2025, time.November+1, 13, 0, 0, 0, 0, time.UTC))
443+
case 14:
444+
return t.After(time.Date(2026, time.November+1, 12, 0, 0, 0, 0, time.UTC))
445+
case 15:
446+
return t.After(time.Date(2027, time.November+1, 11, 0, 0, 0, 0, time.UTC))
447+
case 16:
448+
return t.After(time.Date(2028, time.November+1, +9, 0, 0, 0, 0, time.UTC))
449+
case 17:
450+
return t.After(time.Date(2029, time.November+1, +8, 0, 0, 0, 0, time.UTC))
451+
}
452+
453+
return false
454+
}

internal/postgres/config_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"path/filepath"
1515
"strings"
1616
"testing"
17+
"time"
1718

1819
"gotest.tools/v3/assert"
1920
corev1 "k8s.io/api/core/v1"
@@ -506,3 +507,25 @@ EOF
506507
chmod +x /tmp/pg_rewind_tde.sh`))
507508
})
508509
}
510+
511+
func TestReleaseIsFinal(t *testing.T) {
512+
// On November 4th, 2024, PG 10 and 11 were EOL and 12-17 were supported.
513+
testDate, err := time.Parse("2006-Jan-02", "2024-Nov-04")
514+
assert.NilError(t, err)
515+
assert.Check(t, ReleaseIsFinal(10, testDate))
516+
assert.Check(t, ReleaseIsFinal(11, testDate))
517+
assert.Check(t, !ReleaseIsFinal(12, testDate))
518+
assert.Check(t, !ReleaseIsFinal(13, testDate))
519+
assert.Check(t, !ReleaseIsFinal(14, testDate))
520+
assert.Check(t, !ReleaseIsFinal(15, testDate))
521+
assert.Check(t, !ReleaseIsFinal(16, testDate))
522+
assert.Check(t, !ReleaseIsFinal(17, testDate))
523+
524+
// On December 15th, 2024 we alert that PG 12 is EOL
525+
testDate = testDate.AddDate(0, 1, 11)
526+
assert.Check(t, ReleaseIsFinal(12, testDate))
527+
528+
// ReleaseIsFinal covers PG versions 10 and greater. Any version not covered
529+
// by the case statement in ReleaseIsFinal returns false
530+
assert.Check(t, !ReleaseIsFinal(1, testDate))
531+
}

0 commit comments

Comments
 (0)