diff --git a/CHANGELOG.md b/CHANGELOG.md index 7abb63990ee..2aa93a93c77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,7 +33,7 @@ - Kubernetes Workload Scaler: ignore terminated pods ([#2384](https://github.com/kedacore/keda/pull/2384)) - Azure EventHub Scaler: don't expose connection string in metricName ([#2404](https://github.com/kedacore/keda/pull/2404)) - `keda-operator` Cluster Role: add `list` and `watch` access to service accounts ([#2406](https://github.com/kedacore/keda/pull/2406))|([#2410](https://github.com/kedacore/keda/pull/2410)) -- PostgreSQL Scaler: Assign PostgreSQL `userName` to correct attribute ([#2432](https://github.com/kedacore/keda/pull/2432)) +- PostgreSQL Scaler: Assign PostgreSQL `userName` to correct attribute ([#2432](https://github.com/kedacore/keda/pull/2432))|([#2433](https://github.com/kedacore/keda/pull/2433)) - Kafka Scaler: concurrently query brokers for consumer and producer offsets ([#2405](https://github.com/kedacore/keda/pull/2405)) - Delete the cache entry when a ScaledObject is deleted ([#2408](https://github.com/kedacore/keda/pull/2408)) diff --git a/pkg/scalers/postgresql_scaler.go b/pkg/scalers/postgresql_scaler.go index 82ecacda765..99a7fb7daf0 100644 --- a/pkg/scalers/postgresql_scaler.go +++ b/pkg/scalers/postgresql_scaler.go @@ -26,13 +26,7 @@ type postgreSQLScaler struct { type postgreSQLMetadata struct { targetQueryValue int connection string - userName string - password string - host string - port string query string - dbName string - sslmode string metricName string scalerIndex int } @@ -81,38 +75,47 @@ func parsePostgreSQLMetadata(config *ScalerConfig) (*postgreSQLMetadata, error) case config.TriggerMetadata["connectionFromEnv"] != "": meta.connection = config.ResolvedEnv[config.TriggerMetadata["connectionFromEnv"]] default: - meta.connection = "" - var err error - meta.host, err = GetFromAuthOrMeta(config, "host") + host, err := GetFromAuthOrMeta(config, "host") if err != nil { return nil, err } - meta.port, err = GetFromAuthOrMeta(config, "port") + port, err := GetFromAuthOrMeta(config, "port") if err != nil { return nil, err } - meta.userName, err = GetFromAuthOrMeta(config, "userName") + userName, err := GetFromAuthOrMeta(config, "userName") if err != nil { return nil, err } - meta.dbName, err = GetFromAuthOrMeta(config, "dbName") + dbName, err := GetFromAuthOrMeta(config, "dbName") if err != nil { return nil, err } - meta.sslmode, err = GetFromAuthOrMeta(config, "sslmode") + sslmode, err := GetFromAuthOrMeta(config, "sslmode") if err != nil { return nil, err } + var password string if config.AuthParams["password"] != "" { - meta.password = config.AuthParams["password"] + password = config.AuthParams["password"] } else if config.TriggerMetadata["passwordFromEnv"] != "" { - meta.password = config.ResolvedEnv[config.TriggerMetadata["passwordFromEnv"]] + password = config.ResolvedEnv[config.TriggerMetadata["passwordFromEnv"]] } + + meta.connection = fmt.Sprintf( + "host=%s port=%s user=%s dbname=%s sslmode=%s password=%s", + host, + port, + userName, + dbName, + sslmode, + password, + ) } if val, ok := config.TriggerMetadata["metricName"]; ok { @@ -125,21 +128,7 @@ func parsePostgreSQLMetadata(config *ScalerConfig) (*postgreSQLMetadata, error) } func getConnection(meta *postgreSQLMetadata) (*sql.DB, error) { - var connStr string - if meta.connection != "" { - connStr = meta.connection - } else { - connStr = fmt.Sprintf( - "host=%s port=%s user=%s dbname=%s sslmode=%s password=%s", - meta.host, - meta.port, - meta.userName, - meta.dbName, - meta.sslmode, - meta.password, - ) - } - db, err := sql.Open("postgres", connStr) + db, err := sql.Open("postgres", meta.connection) if err != nil { postgreSQLLog.Error(err, fmt.Sprintf("Found error opening postgreSQL: %s", err)) return nil, err diff --git a/pkg/scalers/postgresql_scaler_test.go b/pkg/scalers/postgresql_scaler_test.go index 2be34f01d43..d75d80bcd9e 100644 --- a/pkg/scalers/postgresql_scaler_test.go +++ b/pkg/scalers/postgresql_scaler_test.go @@ -9,14 +9,6 @@ type parsePostgreSQLMetadataTestData struct { metadata map[string]string } -type postgreSQLMetricIdentifier struct { - metadataTestData *parsePostgreSQLMetadataTestData - resolvedEnv map[string]string - authParam map[string]string - scaleIndex int - name string -} - var testPostgreSQLMetdata = []parsePostgreSQLMetadataTestData{ // connection with username and password {metadata: map[string]string{"query": "test_query", "targetQueryValue": "5", "connectionFromEnv": "test_connection_string"}}, @@ -32,13 +24,17 @@ var testPostgreSQLMetdata = []parsePostgreSQLMetadataTestData{ {metadata: map[string]string{"query": "test_query", "targetQueryValue": "5", "host": "test_host", "port": "test_port", "userName": "test_user_name", "dbName": "test_db_name", "sslmode": "test_ssl_mode", "metricName": "scaler_sql_data"}}, } +type postgreSQLMetricIdentifier struct { + metadataTestData *parsePostgreSQLMetadataTestData + resolvedEnv map[string]string + authParam map[string]string + scaleIndex int + name string +} + var postgreSQLMetricIdentifiers = []postgreSQLMetricIdentifier{ {&testPostgreSQLMetdata[0], map[string]string{"test_connection_string": "postgresql://localhost:5432"}, nil, 0, "s0-postgresql"}, {&testPostgreSQLMetdata[1], map[string]string{"test_connection_string2": "postgresql://test@localhost"}, nil, 1, "s1-postgresql"}, - {&testPostgreSQLMetdata[2], nil, map[string]string{"connection": "postgresql://user:password@localhost:5432/dbname"}, 2, "s2-postgresql"}, - {&testPostgreSQLMetdata[3], nil, map[string]string{"connection": "postgresql://Username123:secret@localhost"}, 3, "s3-postgresql-scaler_sql_data2"}, - {&testPostgreSQLMetdata[4], nil, map[string]string{"connection": "postgresql://user:password@localhost:5432/dbname?app_name=test"}, 4, "s4-postgresql"}, - {&testPostgreSQLMetdata[5], nil, map[string]string{"connection": "postgresql://Username123:secret@localhost"}, 5, "s5-postgresql-scaler_sql_data"}, } func TestPosgresSQLGetMetricSpecForScaling(t *testing.T) { @@ -57,9 +53,33 @@ func TestPosgresSQLGetMetricSpecForScaling(t *testing.T) { } } -var testPostgresResolvedEnv = map[string]string{ - "POSTGRE_PASSWORD": "pass", - "POSTGRE_CONN_STR": "test_conn_str", +type postgreSQLConnectionStringTestData struct { + metadata map[string]string + resolvedEnv map[string]string + authParam map[string]string + connectionString string +} + +var testPostgreSQLConnectionstring = []postgreSQLConnectionStringTestData{ + // from environment + {metadata: map[string]string{"query": "test_query", "targetQueryValue": "5", "connectionFromEnv": "CONNECTION_ENV"}, resolvedEnv: map[string]string{"CONNECTION_ENV": "test_connection_from_env"}, connectionString: "test_connection_from_env"}, + // from authentication + {metadata: map[string]string{"query": "test_query", "targetQueryValue": "5"}, authParam: map[string]string{"connection": "test_connection_from_auth"}, connectionString: "test_connection_from_auth"}, + // from meta + {metadata: map[string]string{"query": "test_query", "targetQueryValue": "5", "host": "localhost", "port": "1234", "dbName": "testDb", "userName": "user", "sslmode": "required"}, connectionString: "host=localhost port=1234 user=user dbname=testDb sslmode=required password="}, +} + +func TestPosgresSQLConnectionStringGeneration(t *testing.T) { + for _, testData := range testPostgreSQLConnectionstring { + meta, err := parsePostgreSQLMetadata(&ScalerConfig{ResolvedEnv: testData.resolvedEnv, TriggerMetadata: testData.metadata, AuthParams: testData.authParam, ScalerIndex: 0}) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + + if meta.connection != testData.connectionString { + t.Errorf("Error generating connectionString, expected '%s' and get '%s'", testData.connectionString, meta.connection) + } + } } type parsePostgresMetadataTestData struct { @@ -69,6 +89,11 @@ type parsePostgresMetadataTestData struct { raisesError bool } +var testPostgresResolvedEnv = map[string]string{ + "POSTGRE_PASSWORD": "pass", + "POSTGRE_CONN_STR": "test_conn_str", +} + var testPostgresMetadata = []parsePostgresMetadataTestData{ // No metadata {