diff --git a/api/v1/store.go b/api/v1/store.go index 480ec29..4d021ae 100644 --- a/api/v1/store.go +++ b/api/v1/store.go @@ -249,8 +249,8 @@ type S3Storage struct { } type DatabaseSpec struct { - // +kubebuilder:validation:MinLength=1 - Host string `json:"host"` + Host string `json:"host,omitempty"` + HostRef SecretRef `json:"hostRef,omitempty"` // +kubebuilder:default=3306 Port int32 `json:"port"` // +kubebuilder:validation:MinLength=1 diff --git a/internal/controller/store_controller.go b/internal/controller/store_controller.go index bf0dc7e..d35539a 100644 --- a/internal/controller/store_controller.go +++ b/internal/controller/store_controller.go @@ -267,7 +267,30 @@ func (r *StoreReconciler) ensureAppSecrets(ctx context.Context, store *v1.Store) Name: store.GetSecretName(), } - storeSecret := new(corev1.Secret) + if store.Spec.Database.Host == "" && store.Spec.Database.HostRef.Name == "" { + return fmt.Errorf("database host is empty for store %s. Eigther set host or a hostRef", store.Name) + } + + var dbHost string + if store.Spec.Database.HostRef.Name != "" { + hostSecret := new(corev1.Secret) + if err := r.Client.Get(ctx, types.NamespacedName{ + Namespace: store.Namespace, + Name: store.Spec.Database.HostRef.Name, + }, hostSecret); err != nil { + if k8serrors.IsNotFound(err) { + r.Recorder.Event(store, "Warning", "DB secret not found", + fmt.Sprintf("Missing database secret for Store %s in namespace %s", + store.Name, + store.Namespace)) + return nil + } + return fmt.Errorf("can't read database secret: %w", err) + } + dbHost = string(hostSecret.Data[store.Spec.Database.HostRef.Key]) + } else { + dbHost = store.Spec.Database.Host + } dbSecret := new(corev1.Secret) if err := r.Client.Get(ctx, types.NamespacedName{ @@ -284,10 +307,11 @@ func (r *StoreReconciler) ensureAppSecrets(ctx context.Context, store *v1.Store) return fmt.Errorf("can't read database secret: %w", err) } + storeSecret := new(corev1.Secret) if err = r.Get(ctx, nn, storeSecret); client.IgnoreNotFound(err) != nil { return fmt.Errorf("get store secret: %w", err) } - if err = secret.GenerateStoreSecret(ctx, store, storeSecret, dbSecret.Data[store.Spec.Database.PasswordSecretRef.Key]); err != nil { + if err = secret.GenerateStoreSecret(ctx, store, storeSecret, dbHost, dbSecret.Data[store.Spec.Database.PasswordSecretRef.Key]); err != nil { return fmt.Errorf("fill store secret: %w", err) } storeSecret.Name = store.GetSecretName() diff --git a/internal/secret/secret.go b/internal/secret/secret.go index 8af57e4..d00f120 100644 --- a/internal/secret/secret.go +++ b/internal/secret/secret.go @@ -25,7 +25,7 @@ const ( rsaKeySize = 2024 ) -func GenerateStoreSecret(ctx context.Context, store *v1.Store, secret *corev1.Secret, p []byte) error { +func GenerateStoreSecret(ctx context.Context, store *v1.Store, secret *corev1.Secret, dbHost string, p []byte) error { if secret.Data == nil { secret.Data = make(map[string][]byte) } @@ -59,7 +59,7 @@ func GenerateStoreSecret(ctx context.Context, store *v1.Store, secret *corev1.Se secret.Data["jwt-public-key"] = []byte(base64.StdEncoding.EncodeToString(publicKey)) } - secret.Data["database-url"] = util.GenerateDatabaseURLForShopware(&store.Spec.Database, p) + secret.Data["database-url"] = util.GenerateDatabaseURLForShopware(&store.Spec.Database, dbHost, p) return nil } diff --git a/internal/util/db.go b/internal/util/db.go index 7aeb575..540559e 100644 --- a/internal/util/db.go +++ b/internal/util/db.go @@ -11,13 +11,13 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" ) -func GenerateDatabaseURLForShopware(db *v1.DatabaseSpec, p []byte) []byte { +func GenerateDatabaseURLForShopware(db *v1.DatabaseSpec, dbHost string, p []byte) []byte { urlP := url.QueryEscape(string(p)) plain := fmt.Sprintf( "mysql://%s:%s@%s:%d/%s?serverVersion=%s", db.User, urlP, - db.Host, + dbHost, db.Port, db.Name, db.Version,