feat(ci): update Postgres minor version and delete temporary tags

This commit is contained in:
Peter 2025-03-26 13:51:04 +01:00
parent 366ceece24
commit 87a06dac66
Signed by: prskr
GPG key ID: F56BED6903BC5E37
25 changed files with 422 additions and 321 deletions

View file

@ -195,7 +195,7 @@ func (r *APIGatewayReconciler) apiTargetServiceEventHandler() handler.TypedEvent
return nil
}
if err := r.Client.List(ctx, &list, client.InNamespace(obj.GetNamespace())); err != nil {
if err := r.List(ctx, &list, client.InNamespace(obj.GetNamespace())); err != nil {
logger.Error(err, "Failed to list Services to map updates to APIGateway reconciliation requests")
return nil
}

View file

@ -19,7 +19,7 @@ package controller
import (
"bytes"
"context"
"hash/fnv"
"crypto/rand"
"maps"
"net/url"
"time"
@ -38,7 +38,6 @@ import (
"code.icb4dc0.de/prskr/supabase-operator/internal/db"
"code.icb4dc0.de/prskr/supabase-operator/internal/errx"
"code.icb4dc0.de/prskr/supabase-operator/internal/meta"
"code.icb4dc0.de/prskr/supabase-operator/internal/pw"
"code.icb4dc0.de/prskr/supabase-operator/internal/supabase"
)
@ -169,8 +168,6 @@ func (r *CoreDbReconciler) ensureDbRolesSecrets(
core.Status.Database.Roles = make(map[string][]byte)
}
hash := fnv.New64a()
for secretName, role := range roles {
secretLogger := logger.WithValues("secret_name", secretName, "role_name", role.String())
@ -203,21 +200,23 @@ func (r *CoreDbReconciler) ensureDbRolesSecrets(
var requireStatusUpdate bool
// if the current role is the same user as in the DSN, we're keeping the password as is
if value := credentialsSecret.Data[corev1.BasicAuthPasswordKey]; len(value) == 0 || (role.String() == dsnUser && !bytes.Equal(credentialsSecret.Data[corev1.BasicAuthPasswordKey], []byte(dsnPW))) {
if role.String() == dsnUser {
credentialsSecret.Data[corev1.BasicAuthPasswordKey] = []byte(dsnPW)
} else {
credentialsSecret.Data[corev1.BasicAuthPasswordKey] = pw.GeneratePW(24, nil)
credentialsSecret.Data[corev1.BasicAuthPasswordKey] = []byte(rand.Text())
}
secretLogger.Info("Update database role to match secret credentials")
if err := rolesMgr.UpdateRolePassword(ctx, role.String(), credentialsSecret.Data[corev1.BasicAuthPasswordKey]); err != nil {
return err
}
core.Status.Database.Roles[role.String()] = hash.Sum(credentialsSecret.Data[corev1.BasicAuthPasswordKey])
core.Status.Database.Roles[role.String()] = HashBytes(credentialsSecret.Data[corev1.BasicAuthPasswordKey])
requireStatusUpdate = true
} else {
if bytes.Equal(core.Status.Database.Roles[role.String()], hash.Sum(credentialsSecret.Data[corev1.BasicAuthPasswordKey])) {
if bytes.Equal(core.Status.Database.Roles[role.String()], HashBytes(credentialsSecret.Data[corev1.BasicAuthPasswordKey])) {
logger.Info("Role password is up to date", "role_name", role.String())
} else {
if err := rolesMgr.UpdateRolePassword(ctx, role.String(), credentialsSecret.Data[corev1.BasicAuthPasswordKey]); err != nil {
@ -225,7 +224,7 @@ func (r *CoreDbReconciler) ensureDbRolesSecrets(
}
requireStatusUpdate = true
}
core.Status.Database.Roles[role.String()] = hash.Sum(credentialsSecret.Data[corev1.BasicAuthPasswordKey])
core.Status.Database.Roles[role.String()] = HashBytes(credentialsSecret.Data[corev1.BasicAuthPasswordKey])
}
credentialsSecret.Type = corev1.SecretTypeBasicAuth

View file

@ -91,15 +91,14 @@ func (r *StorageS3CredentialsReconciler) reconcileS3StorageSecret(
},
}
if err := r.Get(ctx, client.ObjectKeyFromObject(s3CredsSecret), s3CredsSecret); err != nil {
_, err := controllerutil.CreateOrUpdate(ctx, r.Client, s3CredsSecret, func() error {
return controllerutil.SetControllerReference(storage, s3CredsSecret, r.Scheme)
})
if err != nil {
return err
}
if err := controllerutil.SetControllerReference(storage, s3CredsSecret, r.Scheme); err != nil {
return err
}
return r.Update(ctx, s3CredsSecret)
return nil
}
func (r *StorageS3CredentialsReconciler) reconcileS3ProtoSecret(

View file

@ -166,7 +166,7 @@ func (r *APIGatewayReconciler) endpointSliceEventHandler() handler.TypedEventHan
}
logger.Info("Triggering APIGateway reconciliation", "obj_name", obj.GetName(), "obj_namespace", obj.GetNamespace())
if err := r.Client.List(ctx, &apiGatewayList, client.InNamespace(endpointSlice.Namespace)); err != nil {
if err := r.List(ctx, &apiGatewayList, client.InNamespace(endpointSlice.Namespace)); err != nil {
logger.Error(err, "failed to list APIGateways to determine reconcile targets")
return nil
}

View file

@ -334,7 +334,7 @@ func (s *StudioCluster) basicAuthHttpFilter(ctx context.Context, gateway *supaba
},
}
if err := s.Client.Get(ctx, client.ObjectKeyFromObject(&usersSecret), &usersSecret); err != nil {
if err := s.Get(ctx, client.ObjectKeyFromObject(&usersSecret), &usersSecret); err != nil {
if client.IgnoreNotFound(err) != nil {
return nil, fmt.Errorf("failed to fetch credentials secret: %w", err)
}

View file

@ -19,6 +19,7 @@ package pw
import (
"bytes"
"math/rand/v2"
"time"
)
func GeneratePW(length uint, random *rand.Rand) []byte {
@ -28,7 +29,8 @@ func GeneratePW(length uint, random *rand.Rand) []byte {
)
if random == nil {
random = rand.New(rand.NewPCG(0, 0))
now := time.Now()
random = rand.New(rand.NewPCG(uint64(now.Year()), uint64(now.UnixNano())))
}
for range length {

View file

@ -42,15 +42,15 @@ var Images = struct {
}{
EdgeRuntime: ImageRef{
Repository: "supabase/edge-runtime",
Tag: "v1.67.0",
Tag: "v1.67.4",
},
Envoy: ImageRef{
Repository: "envoyproxy/envoy",
Tag: "distroless-v1.33.0",
Tag: "distroless-v1.33.2",
},
Gotrue: ImageRef{
Repository: "supabase/gotrue",
Tag: "v2.167.0",
Tag: "v2.170.0",
},
ImgProxy: ImageRef{
Repository: "darthsim/imgproxy",
@ -58,22 +58,22 @@ var Images = struct {
},
PostgresMeta: ImageRef{
Repository: "supabase/postgres-meta",
Tag: "v0.84.2",
Tag: "v0.87.1",
},
Postgrest: ImageRef{
Repository: "postgrest/postgrest",
Tag: "v12.2.0",
Tag: "v12.2.8",
},
Realtime: ImageRef{
Repository: "supabase/realtime",
Tag: "v2.34.7",
Tag: "v2.34.43",
},
Storage: ImageRef{
Repository: "supabase/storage-api",
Tag: "v1.14.5",
Tag: "v1.19.3",
},
Studio: ImageRef{
Repository: "supabase/studio",
Tag: "20250113-83c9420",
Tag: "20250317-6955350",
},
}

View file

@ -46,6 +46,7 @@ import (
// as it is used only for temporary operations and does not need to be deeply copied.
type CoreCustomDefaulter struct {
client.Client
Scheme *runtime.Scheme
}
var _ webhook.CustomDefaulter = &CoreCustomDefaulter{}
@ -63,6 +64,16 @@ func (d *CoreCustomDefaulter) Default(ctx context.Context, obj runtime.Object) e
return fmt.Errorf("ensuring JWT secret: %w", err)
}
if err := d.defaultDatabase(ctx, core); err != nil {
return fmt.Errorf("ensuring database setup: %w", err)
}
return nil
}
func (d *CoreCustomDefaulter) defaultDatabase(ctx context.Context, core *supabasev1alpha1.Core) error {
corelog.Info("Defaulting database")
corelog.Info("Defaulting database roles")
if !core.Spec.Database.Roles.SelfManaged {
const roleCredsSecretNameTemplate = "%s-db-creds-%s"
@ -92,6 +103,30 @@ func (d *CoreCustomDefaulter) Default(ctx context.Context, obj runtime.Object) e
}
}
if plaintextDsn := core.Spec.Database.DSN; plaintextDsn != nil && *plaintextDsn != "" {
dsnSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: core.Spec.Database.DSNSecretRef.Name,
Namespace: core.Namespace,
},
}
_, err := controllerutil.CreateOrUpdate(ctx, d.Client, dsnSecret, func() error {
if dsnSecret.Data == nil {
dsnSecret.Data = make(map[string][]byte)
}
dsnSecret.Data[core.Spec.Database.DSNSecretRef.Key] = []byte(*plaintextDsn)
return nil
})
if err != nil {
return fmt.Errorf("create or update DSN secret: %w", err)
}
core.Spec.Database.DSN = nil
}
return nil
}

View file

@ -118,7 +118,7 @@ func (v *CoreCustomValidator) validateDb(
if dbSpec.Roles.SelfManaged {
doesSecretExists := func(ctx context.Context, name string) (exists bool, err error) {
var secret corev1.Secret
if err := v.Client.Get(ctx, types.NamespacedName{Namespace: core.Namespace, Name: name}, &secret); err == nil {
if err := v.Get(ctx, types.NamespacedName{Namespace: core.Namespace, Name: name}, &secret); err == nil {
return true, nil
} else if client.IgnoreNotFound(err) == nil {
return false, nil

View file

@ -42,7 +42,7 @@ func SetupAPIGatewayWebhookWithManager(mgr ctrl.Manager, cfg WebhookConfig) erro
func SetupCoreWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).For(&supabasev1alpha1.Core{}).
WithValidator(&CoreCustomValidator{Client: mgr.GetClient()}).
WithDefaulter(&CoreCustomDefaulter{Client: mgr.GetClient()}).
WithDefaulter(&CoreCustomDefaulter{Client: mgr.GetClient(), Scheme: mgr.GetScheme()}).
Complete()
}