PostgreSQL: Support PGPASSFILE by making password optional (#108856)

* datasource(postgresql): add support of pgpass file

* remove `required` label for password field

* set `runPostgresTests` back to false

* fix after merge conflict

* add pgx_test

* set `runPostgresTests` back to `false`

* Add `no password` test case to the `pgx_test.go` as well

* fix `postgres_pgx_test.go`

* Update datasource docs

* docs wording

* docs: `datasource` -> `data source`

* Update docs/sources/datasources/postgres/configure/_index.md

Co-authored-by: Zoltán Bedi <zoltan.bedi@gmail.com>

* run prettier - docs

---------

Co-authored-by: Zoltán Bedi <zoltan.bedi@gmail.com>
This commit is contained in:
Taras
2025-09-26 15:23:40 +01:00
committed by GitHub
parent 00fb2e9537
commit e7f57446c1
5 changed files with 109 additions and 32 deletions
@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"math/rand"
"os"
"strings"
"testing"
"time"
@@ -41,7 +42,7 @@ func TestIntegrationGenerateConnectionStringPGX(t *testing.T) {
password: "password",
database: "database",
tlsSettings: tlsSettings{Mode: "verify-full"},
expConnStr: "user='user' password='password' host='/var/run/postgresql' dbname='database' sslmode='verify-full'",
expConnStr: "user='user' host='/var/run/postgresql' dbname='database' password='password' sslmode='verify-full'",
},
{
desc: "TCP host",
@@ -50,7 +51,7 @@ func TestIntegrationGenerateConnectionStringPGX(t *testing.T) {
password: "password",
database: "database",
tlsSettings: tlsSettings{Mode: "verify-full"},
expConnStr: "user='user' password='password' host='host' dbname='database' sslmode='verify-full'",
expConnStr: "user='user' host='host' dbname='database' password='password' sslmode='verify-full'",
},
{
desc: "verify-ca automatically adds disable-sni",
@@ -59,7 +60,7 @@ func TestIntegrationGenerateConnectionStringPGX(t *testing.T) {
password: "password",
database: "database",
tlsSettings: tlsSettings{Mode: "verify-ca"},
expConnStr: "user='user' password='password' host='host' dbname='database' port=1234 sslmode='verify-ca' sslsni=0",
expConnStr: "user='user' host='host' dbname='database' password='password' port=1234 sslmode='verify-ca' sslsni=0",
},
{
desc: "TCP/port host",
@@ -68,7 +69,7 @@ func TestIntegrationGenerateConnectionStringPGX(t *testing.T) {
password: "password",
database: "database",
tlsSettings: tlsSettings{Mode: "verify-full"},
expConnStr: "user='user' password='password' host='host' dbname='database' port=1234 sslmode='verify-full'",
expConnStr: "user='user' host='host' dbname='database' password='password' port=1234 sslmode='verify-full'",
},
{
desc: "Ipv6 host",
@@ -77,7 +78,7 @@ func TestIntegrationGenerateConnectionStringPGX(t *testing.T) {
password: "password",
database: "database",
tlsSettings: tlsSettings{Mode: "verify-full"},
expConnStr: "user='user' password='password' host='::1' dbname='database' sslmode='verify-full'",
expConnStr: "user='user' host='::1' dbname='database' password='password' sslmode='verify-full'",
},
{
desc: "Ipv6/port host",
@@ -86,7 +87,7 @@ func TestIntegrationGenerateConnectionStringPGX(t *testing.T) {
password: "password",
database: "database",
tlsSettings: tlsSettings{Mode: "verify-full"},
expConnStr: "user='user' password='password' host='::1' dbname='database' port=1234 sslmode='verify-full'",
expConnStr: "user='user' host='::1' dbname='database' password='password' port=1234 sslmode='verify-full'",
},
{
desc: "Invalid port",
@@ -103,7 +104,7 @@ func TestIntegrationGenerateConnectionStringPGX(t *testing.T) {
password: `p'\assword`,
database: "database",
tlsSettings: tlsSettings{Mode: "verify-full"},
expConnStr: `user='user' password='p\'\\assword' host='host' dbname='database' sslmode='verify-full'`,
expConnStr: `user='user' host='host' dbname='database' password='p\'\\assword' sslmode='verify-full'`,
},
{
desc: "User/DB with single quote and backslash",
@@ -112,7 +113,7 @@ func TestIntegrationGenerateConnectionStringPGX(t *testing.T) {
password: `password`,
database: `d'\atabase`,
tlsSettings: tlsSettings{Mode: "verify-full"},
expConnStr: `user='u\'\\ser' password='password' host='host' dbname='d\'\\atabase' sslmode='verify-full'`,
expConnStr: `user='u\'\\ser' host='host' dbname='d\'\\atabase' password='password' sslmode='verify-full'`,
},
{
desc: "Custom TLS mode disabled",
@@ -121,7 +122,7 @@ func TestIntegrationGenerateConnectionStringPGX(t *testing.T) {
password: "password",
database: "database",
tlsSettings: tlsSettings{Mode: "disable"},
expConnStr: "user='user' password='password' host='host' dbname='database' sslmode='disable'",
expConnStr: "user='user' host='host' dbname='database' password='password' sslmode='disable'",
},
{
desc: "Custom TLS mode verify-full with certificate files",
@@ -135,9 +136,18 @@ func TestIntegrationGenerateConnectionStringPGX(t *testing.T) {
CertFile: "i/am/coding/client.crt",
CertKeyFile: "i/am/coding/client.key",
},
expConnStr: "user='user' password='password' host='host' dbname='database' sslmode='verify-full' " +
expConnStr: "user='user' host='host' dbname='database' password='password' sslmode='verify-full' " +
"sslrootcert='i/am/coding/ca.crt' sslcert='i/am/coding/client.crt' sslkey='i/am/coding/client.key'",
},
{
desc: "No password",
host: "host",
user: "user",
password: "",
database: "database",
tlsSettings: tlsSettings{Mode: "verify-full"},
expConnStr: "user='user' host='host' dbname='database' sslmode='verify-full'",
},
}
for _, tt := range testCases {
t.Run(tt.desc, func(t *testing.T) {
@@ -1555,4 +1565,18 @@ func TestIntegrationPostgresPGX(t *testing.T) {
require.Equal(t, "updated", *nameValue)
})
})
t.Run("Test Postgres connection with pgpass file", func(t *testing.T) {
require.NoError(t, preparePgpassFile(t))
require.FileExists(t, os.Getenv("PGPASSFILE"), "Make sure that PGPASSFILE is set and file exists")
cnnstr := postgresTestDBConnString()
require.NotContains(t, cnnstr, "password=", "Make sure that password is not in the connection string")
pgpassPool, _, err := newPostgresPGX(t.Context(), "error", 10000, dsInfo, cnnstr, logger, backend.DataSourceInstanceSettings{})
require.NoError(t, err)
_, err = pgpassPool.Query(t.Context(), "SELECT 1") // Test connection
require.NoError(t, err)
})
}