PostgreSQL: Remove feature toggle postgresDSUsePGX (#113675)
* PostgreSQL: Remove feature toggle `postgresDSUsePGX` * Fix tests and linting * Address review comments
This commit is contained in:
@@ -2,7 +2,6 @@ package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
@@ -16,63 +15,12 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data/sqlutil"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"github.com/lib/pq"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
||||
sqlengpgx "github.com/grafana/grafana/pkg/tsdb/grafana-postgresql-datasource/pgx"
|
||||
"github.com/grafana/grafana/pkg/tsdb/grafana-postgresql-datasource/sqleng"
|
||||
)
|
||||
|
||||
func newPostgres(ctx context.Context, userFacingDefaultError string, rowLimit int64, dsInfo sqleng.DataSourceInfo, cnnstr string, logger log.Logger, settings backend.DataSourceInstanceSettings) (*sql.DB, *sqleng.DataSourceHandler, error) {
|
||||
connector, err := pq.NewConnector(cnnstr)
|
||||
if err != nil {
|
||||
logger.Error("postgres connector creation failed", "error", err)
|
||||
return nil, nil, fmt.Errorf("postgres connector creation failed")
|
||||
}
|
||||
|
||||
proxyClient, err := settings.ProxyClient(ctx)
|
||||
if err != nil {
|
||||
logger.Error("postgres proxy creation failed", "error", err)
|
||||
return nil, nil, fmt.Errorf("postgres proxy creation failed")
|
||||
}
|
||||
|
||||
if proxyClient.SecureSocksProxyEnabled() {
|
||||
dialer, err := proxyClient.NewSecureSocksProxyContextDialer()
|
||||
if err != nil {
|
||||
logger.Error("postgres proxy creation failed", "error", err)
|
||||
return nil, nil, fmt.Errorf("postgres proxy creation failed")
|
||||
}
|
||||
postgresDialer := newPostgresProxyDialer(dialer)
|
||||
// update the postgres dialer with the proxy dialer
|
||||
connector.Dialer(postgresDialer)
|
||||
}
|
||||
|
||||
config := sqleng.DataPluginConfiguration{
|
||||
DSInfo: dsInfo,
|
||||
MetricColumnTypes: []string{"UNKNOWN", "TEXT", "VARCHAR", "CHAR"},
|
||||
RowLimit: rowLimit,
|
||||
}
|
||||
|
||||
queryResultTransformer := postgresQueryResultTransformer{}
|
||||
|
||||
db := sql.OpenDB(connector)
|
||||
|
||||
db.SetMaxOpenConns(config.DSInfo.JsonData.MaxOpenConns)
|
||||
db.SetMaxIdleConns(config.DSInfo.JsonData.MaxIdleConns)
|
||||
db.SetConnMaxLifetime(time.Duration(config.DSInfo.JsonData.ConnMaxLifetime) * time.Second)
|
||||
|
||||
handler, err := sqleng.NewQueryDataHandler(userFacingDefaultError, db, config, &queryResultTransformer, newPostgresMacroEngine(dsInfo.JsonData.Timescaledb),
|
||||
logger)
|
||||
if err != nil {
|
||||
logger.Error("Failed connecting to Postgres", "err", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
logger.Debug("Successfully connected to Postgres")
|
||||
return db, handler, nil
|
||||
}
|
||||
|
||||
func newPostgresPGX(ctx context.Context, userFacingDefaultError string, rowLimit int64, dsInfo sqleng.DataSourceInfo, cnnstr string, logger log.Logger, settings backend.DataSourceInstanceSettings) (*pgxpool.Pool, *sqlengpgx.DataSourceHandler, error) {
|
||||
func newPostgres(ctx context.Context, userFacingDefaultError string, rowLimit int64, dsInfo sqleng.DataSourceInfo, cnnstr string, logger log.Logger, settings backend.DataSourceInstanceSettings) (*pgxpool.Pool, *sqleng.DataSourceHandler, error) {
|
||||
pgxConf, err := pgxpool.ParseConfig(cnnstr)
|
||||
if err != nil {
|
||||
logger.Error("postgres config creation failed", "error", err)
|
||||
@@ -92,7 +40,7 @@ func newPostgresPGX(ctx context.Context, userFacingDefaultError string, rowLimit
|
||||
return nil, nil, fmt.Errorf("postgres proxy creation failed")
|
||||
}
|
||||
|
||||
pgxConf.ConnConfig.DialFunc = newPgxDialFunc(dialer)
|
||||
pgxConf.ConnConfig.DialFunc = newDialFunc(dialer)
|
||||
}
|
||||
|
||||
// by default pgx resolves hostnames to ip addresses. we must avoid this.
|
||||
@@ -101,7 +49,7 @@ func newPostgresPGX(ctx context.Context, userFacingDefaultError string, rowLimit
|
||||
return []string{host}, nil
|
||||
}
|
||||
|
||||
config := sqlengpgx.DataPluginConfiguration{
|
||||
config := sqleng.DataPluginConfiguration{
|
||||
DSInfo: dsInfo,
|
||||
MetricColumnTypes: []string{"unknown", "text", "varchar", "char", "bpchar"},
|
||||
RowLimit: rowLimit,
|
||||
@@ -117,7 +65,7 @@ func newPostgresPGX(ctx context.Context, userFacingDefaultError string, rowLimit
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
handler, err := sqlengpgx.NewQueryDataHandler(userFacingDefaultError, p, config, &queryResultTransformer, newPostgresMacroEngine(dsInfo.JsonData.Timescaledb),
|
||||
handler, err := sqleng.NewQueryDataHandler(userFacingDefaultError, p, config, &queryResultTransformer, newPostgresMacroEngine(dsInfo.JsonData.Timescaledb),
|
||||
logger)
|
||||
if err != nil {
|
||||
logger.Error("Failed connecting to Postgres", "err", err)
|
||||
@@ -128,7 +76,7 @@ func newPostgresPGX(ctx context.Context, userFacingDefaultError string, rowLimit
|
||||
return p, handler, nil
|
||||
}
|
||||
|
||||
func NewInstanceSettings(logger log.Logger, dataPath string) datasource.InstanceFactoryFunc {
|
||||
func NewInstanceSettings(logger log.Logger) datasource.InstanceFactoryFunc {
|
||||
return func(ctx context.Context, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
|
||||
cfg := backend.GrafanaConfigFromContext(ctx)
|
||||
sqlCfg, err := cfg.SQL()
|
||||
@@ -171,48 +119,26 @@ func NewInstanceSettings(logger log.Logger, dataPath string) datasource.Instance
|
||||
return nil, err
|
||||
}
|
||||
|
||||
usePGX := cfg.FeatureToggles().IsEnabled("postgresDSUsePGX")
|
||||
|
||||
if usePGX {
|
||||
pgxlogger := logger.FromContext(ctx).With("driver", "pgx")
|
||||
pgxTlsManager := newPgxTlsManager(pgxlogger)
|
||||
pgxTlsSettings, err := pgxTlsManager.getTLSSettings(dsInfo)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Ensure cleanupCertFiles is called after the connection is opened
|
||||
defer pgxTlsManager.cleanupCertFiles(pgxTlsSettings)
|
||||
cnnstr, err := generateConnectionString(dsInfo, pgxTlsSettings, usePGX, pgxlogger)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, handler, err := newPostgresPGX(ctx, userFacingDefaultError, sqlCfg.RowLimit, dsInfo, cnnstr, pgxlogger, settings)
|
||||
if err != nil {
|
||||
pgxlogger.Error("Failed connecting to Postgres", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
pgxlogger.Debug("Successfully connected to Postgres")
|
||||
return handler, nil
|
||||
} else {
|
||||
pqlogger := logger.FromContext(ctx).With("driver", "libpq")
|
||||
tlsManager := newTLSManager(pqlogger, dataPath)
|
||||
tlsSettings, err := tlsManager.getTLSSettings(dsInfo)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
cnnstr, err := generateConnectionString(dsInfo, tlsSettings, usePGX, pqlogger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, handler, err := newPostgres(ctx, userFacingDefaultError, sqlCfg.RowLimit, dsInfo, cnnstr, pqlogger, settings)
|
||||
if err != nil {
|
||||
pqlogger.Error("Failed connecting to Postgres", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
pqlogger.Debug("Successfully connected to Postgres")
|
||||
return handler, nil
|
||||
pgxlogger := logger.FromContext(ctx).With("driver", "pgx")
|
||||
tlsManager := newTLSManager(pgxlogger)
|
||||
tlsSettings, err := tlsManager.getTLSSettings(dsInfo)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Ensure cleanupCertFiles is called after the connection is opened
|
||||
defer tlsManager.cleanupCertFiles(tlsSettings)
|
||||
cnnstr, err := generateConnectionString(dsInfo, tlsSettings, pgxlogger)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, handler, err := newPostgres(ctx, userFacingDefaultError, sqlCfg.RowLimit, dsInfo, cnnstr, pgxlogger, settings)
|
||||
if err != nil {
|
||||
pgxlogger.Error("Failed connecting to Postgres", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
pgxlogger.Debug("Successfully connected to Postgres")
|
||||
return handler, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,7 +228,7 @@ func buildBaseConnectionString(params connectionParams) string {
|
||||
return connStr
|
||||
}
|
||||
|
||||
func generateConnectionString(dsInfo sqleng.DataSourceInfo, tlsSettings tlsSettings, isPGX bool, logger log.Logger) (string, error) {
|
||||
func generateConnectionString(dsInfo sqleng.DataSourceInfo, tlsSettings tlsSettings, logger log.Logger) (string, error) {
|
||||
params, err := parseConnectionParams(dsInfo, logger)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -312,15 +238,6 @@ func generateConnectionString(dsInfo sqleng.DataSourceInfo, tlsSettings tlsSetti
|
||||
|
||||
connStr += fmt.Sprintf(" sslmode='%s'", escape(tlsSettings.Mode))
|
||||
|
||||
// there is an issue with the lib/pq module, the `verify-ca` tls mode
|
||||
// does not work correctly. ( see https://github.com/lib/pq/issues/1106 )
|
||||
// to workaround the problem, if the `verify-ca` mode is chosen,
|
||||
// we disable sslsni.
|
||||
if tlsSettings.Mode == "verify-ca" && !isPGX {
|
||||
logger.Debug("Disabling sslsni for verify-ca mode")
|
||||
connStr += " sslsni=0"
|
||||
}
|
||||
|
||||
// Attach root certificate if provided
|
||||
if tlsSettings.RootCertFile != "" {
|
||||
logger.Debug("Setting server root certificate", "tlsRootCert", tlsSettings.RootCertFile)
|
||||
|
||||
Reference in New Issue
Block a user