github.com/TBD54566975/ftl@v0.219.0/internal/modulecontext/from_secrets.go (about) 1 package modulecontext 2 3 import ( 4 "context" 5 "fmt" 6 "strings" 7 ) 8 9 // DatabasesFromSecrets finds DSNs in secrets and creates a map of databases. 10 // 11 // Secret keys should be in the format FTL_DSN_<MODULENAME>_<DBNAME> 12 func DatabasesFromSecrets(ctx context.Context, module string, secrets map[string][]byte) (map[string]Database, error) { 13 databases := map[string]Database{} 14 for sName, maybeDSN := range secrets { 15 if !strings.HasPrefix(sName, "FTL_DSN_") { 16 continue 17 } 18 // FTL_DSN_<MODULE>_<DBNAME> 19 parts := strings.Split(sName, "_") 20 if len(parts) != 4 { 21 return nil, fmt.Errorf("invalid DSN secret key %q should have format FTL_DSN_<MODULE>_<DBNAME>", sName) 22 } 23 moduleName := strings.ToLower(parts[2]) 24 dbName := strings.ToLower(parts[3]) 25 if !strings.EqualFold(moduleName, module) { 26 continue 27 } 28 dsnStr := string(maybeDSN) 29 dsn := dsnStr[1 : len(dsnStr)-1] // chop leading + trailing quotes 30 db, err := NewDatabase(DBTypePostgres, dsn) 31 if err != nil { 32 return nil, fmt.Errorf("could not create database %q with DSN %q: %w", dbName, maybeDSN, err) 33 } 34 databases[dbName] = db 35 } 36 return databases, nil 37 } 38 39 // DSNSecretKey returns the key for the secret that is expected to hold the DSN for a database. 40 // 41 // The format is FTL_DSN_<MODULE>_<DBNAME> 42 func DSNSecretKey(module, name string) string { 43 return fmt.Sprintf("FTL_DSN_%s_%s", strings.ToUpper(module), strings.ToUpper(name)) 44 } 45 46 // GetDSNFromSecret returns the DSN for a database from the relevant secret 47 func GetDSNFromSecret(module, name string, secrets map[string][]byte) (string, error) { 48 key := DSNSecretKey(module, name) 49 dsn, ok := secrets[key] 50 if !ok { 51 return "", fmt.Errorf("secrets map %v is missing DSN with key %q", secrets, key) 52 } 53 dsnStr := string(dsn) 54 return dsnStr[1 : len(dsnStr)-1], nil // chop leading + trailing quotes 55 }