From 7abc8663564af54abfe4e452dd21aef7fbd4b674 Mon Sep 17 00:00:00 2001 From: patrick Date: Sat, 17 Oct 2026 16:24:14 +0200 Subject: [PATCH] OPS-12: Merge-Folgefehler behoben (NewProvisioner-Signatur, Runtime-DSN) Der automatische Merge von PR #217 (OPS-12) gegen main liess internal/tenant/provisioner.go::ProvisionWithID mit einem nicht mehr existierenden Feld (p.dsnTemplate) zurueck und vergass dort den grantRuntimeRole-Aufruf, den Provision() bereits hat -- echter Build-Fehler, kein reiner Textkonflikt, git markierte ihn nicht als Konflikt. Drei weitere Aufrufer von NewProvisioner (Migrationswerkzeug, Cutover-Orchestrator, Test) riefen noch mit der alten Drei-Parameter- Signatur auf. Alle auf die neue Vier-Parameter-Signatur (Admin-DSN + Runtime-DSN) nachgezogen, wo keine eigene Runtime-DSN-Variable existiert faellt auf dieselbe Vorlage zurueck (admin-only Werkzeuge). Verifiziert auf Host 204: go build/vet sauber, betroffene Pakete (tenant, migrationtenant, cutoverorchestrator, cor01-tenant-migrate) gruen. Einziger verbleibender FAIL (TestAllHTTPServersUseHTTPHarden) ist der bereits bekannte, unabhaengige Befund aus PR #345 (noch nicht gemergt), keine neue Regression. Co-Authored-By: Claude Sonnet 5 --- cmd/cor01-tenant-migrate/main.go | 6 +++++- internal/cutoverorchestrator/steps_core.go | 2 +- internal/migrationtenant/migrate_test.go | 2 +- internal/tenant/provisioner.go | 7 ++++++- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/cmd/cor01-tenant-migrate/main.go b/cmd/cor01-tenant-migrate/main.go index 286b0772..017c4469 100644 --- a/cmd/cor01-tenant-migrate/main.go +++ b/cmd/cor01-tenant-migrate/main.go @@ -42,7 +42,11 @@ func main() { defer adminPool.Close() registry := tenant.NewRegistry(registryPool) - provisioner := tenant.NewProvisioner(adminPool, registry, dsnTemplate) + runtimeDSNTemplate := os.Getenv("NEXARCH_TENANT_RUNTIME_DSN_TEMPLATE") + if runtimeDSNTemplate == "" { + runtimeDSNTemplate = dsnTemplate + } + provisioner := tenant.NewProvisioner(adminPool, registry, dsnTemplate, runtimeDSNTemplate) mapStore := migrationtenant.NewMapStore(registryPool) migrator := migrationtenant.NewMigrator(mapStore, provisioner) diff --git a/internal/cutoverorchestrator/steps_core.go b/internal/cutoverorchestrator/steps_core.go index e97ce4a5..49052fac 100644 --- a/internal/cutoverorchestrator/steps_core.go +++ b/internal/cutoverorchestrator/steps_core.go @@ -241,7 +241,7 @@ func (d *Dryrun) cor01(ctx context.Context) (Outcome, error) { defer adminPool.Close() registry := tenant.NewRegistry(d.registry) - provisioner := tenant.NewProvisioner(adminPool, registry, d.cluster.TenantDSNTemplate()) + provisioner := tenant.NewProvisioner(adminPool, registry, d.cluster.TenantDSNTemplate(), d.cluster.TenantDSNTemplate()) res, err := migrationtenant.NewMigrator(migrationtenant.NewMapStore(d.registry), provisioner).MigrateApproved(ctx) if err != nil { return Outcome{}, err diff --git a/internal/migrationtenant/migrate_test.go b/internal/migrationtenant/migrate_test.go index 6439e990..2677144c 100644 --- a/internal/migrationtenant/migrate_test.go +++ b/internal/migrationtenant/migrate_test.go @@ -72,7 +72,7 @@ func TestMigrateApproved(t *testing.T) { dsnTemplate := strings.Replace(adminDSN, "/postgres?", "/%s?", 1) registry := tenant.NewRegistry(registryPool) - provisioner := tenant.NewProvisioner(adminPool, registry, dsnTemplate) + provisioner := tenant.NewProvisioner(adminPool, registry, dsnTemplate, dsnTemplate) mapStore := NewMapStore(registryPool) migrator := NewMigrator(mapStore, provisioner) diff --git a/internal/tenant/provisioner.go b/internal/tenant/provisioner.go index 4e81006d..e4b93fdd 100644 --- a/internal/tenant/provisioner.go +++ b/internal/tenant/provisioner.go @@ -225,12 +225,17 @@ func (p *Provisioner) ProvisionWithID(ctx context.Context, id, slug, name string return Tenant{}, fmt.Errorf("tenant-datenbank isolieren (revoke connect from public): %w", err) } + if err := p.grantRuntimeRole(ctx, dbName); err != nil { + p.rollbackDatabase(ctx, dbName) + return Tenant{}, fmt.Errorf("laufzeit-rolle berechtigen: %w", err) + } + t := Tenant{ ID: id, Slug: slug, Name: name, DBName: dbName, - DBDSN: fmt.Sprintf(p.dsnTemplate, dbName), + DBDSN: fmt.Sprintf(p.runtimeDSNTemplate, dbName), Status: StatusActive, }