feat(database): connect postgres via socket and read config from env _FILE secrets (#2061)

* feat(database): connect postgres via socket

* feat(config): read env var secrets from file

* docs: explain env var secrets

* refactor: generate postgres dsn
This commit is contained in:
ze0s 2025-05-05 21:15:24 +02:00 committed by GitHub
parent 24648e45f7
commit fe4f385a22
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 345 additions and 76 deletions

View file

@ -5,6 +5,9 @@ package database
import (
"database/sql"
"fmt"
"net"
"net/url"
"github.com/autobrr/autobrr/pkg/errors"
@ -87,3 +90,56 @@ func (db *DB) migratePostgres() error {
return tx.Commit()
}
// PostgresDSN build postgres dsn connect string
func PostgresDSN(host string, port int, user, pass, database, socket, sslMode, extraParams string) (string, error) {
// If no database is provided, return an error
if database == "" {
return "", errors.New("postgres: database name is required")
}
pgDsn, err := url.Parse("postgres://")
if err != nil {
return "", errors.Wrap(err, "could not parse postgres DSN")
}
pgDsn.Path = database
if user != "" {
pgDsn.User = url.UserPassword(user, pass)
}
queryParams := pgDsn.Query()
// Build DSN based on the connection type (TCP vs. Unix socket)
if socket != "" {
// Unix socket connection via the host param
queryParams.Add("host", socket)
} else {
// TCP connection
if host == "" && port == 0 {
return "", errors.New("postgres: host and port are required for TCP connection")
}
if port > 0 {
pgDsn.Host = net.JoinHostPort(host, fmt.Sprintf("%d", port))
} else {
pgDsn.Host = database
}
}
// Add SSL mode if provided
if sslMode != "" {
queryParams.Add("sslmode", sslMode)
}
pgDsn.RawQuery = queryParams.Encode()
// Add any extra parameters
if extraParams != "" {
values, err := url.ParseQuery(extraParams)
if err != nil {
return "", errors.Wrap(err, "could not parse extra params")
}
pgDsn.RawQuery = fmt.Sprintf("%s&%s", pgDsn.RawQuery, values.Encode())
}
return pgDsn.String(), nil
}