Skip to content

Commit

Permalink
fix(mongodb): escape username and password (#3989)
Browse files Browse the repository at this point in the history
Fixes #3992
  • Loading branch information
JorTurFer authored Dec 9, 2022
1 parent 4f7fe2e commit 3e40fc6
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 12 deletions.
10 changes: 8 additions & 2 deletions BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,10 @@ Follow these instructions if you want to debug the KEDA operator using VS Code.
"request": "launch",
"mode": "debug",
"program": "${workspaceFolder}/main.go",
"env": {"WATCH_NAMESPACE": ""}
"env": {
"WATCH_NAMESPACE": "",
"KEDA_CLUSTER_OBJECT_NAMESPACE": "keda"
}
}
]
}
Expand Down Expand Up @@ -171,7 +174,10 @@ Follow these instructions if you want to debug the KEDA metrics server using VS
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/adapter/main.go",
"env": {"WATCH_NAMESPACE": ""},
"env": {
"WATCH_NAMESPACE": "",
"KEDA_CLUSTER_OBJECT_NAMESPACE": "keda"
},
"args": [
"--authentication-kubeconfig=PATH_TO_YOUR_KUBECONFIG",
"--authentication-skip-lookup",
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ To learn more about active deprecations, we recommend checking [GitHub Discussio
- **Azure Blob Scaler** Store forgotten logger ([#3811](https://github.com/kedacore/keda/issues/3811))
- **Datadog Scaler** The last data point of some specific query is always null ([#3906](https://github.com/kedacore/keda/issues/3906))
- **GCP Stackdriver Scalar:** Update Stackdriver client to handle detecting double and int64 value types ([#3777](https://github.com/kedacore/keda/issues/3777))
- **MongoDB Scaler:** Username/password can contain `:/?#[]@` ([#3992](https://github.com/kedacore/keda/issues/3992))
- **New Relic Scaler** Store forgotten logger ([#3945](https://github.com/kedacore/keda/issues/3945))
- **Prometheus Scaler:** Treat Inf the same as Null result ([#3644](https://github.com/kedacore/keda/issues/3644))
- **NATS Jetstream:** Correctly count messages that should be redelivered (waiting for ack) towards keda value ([#3787](https://github.com/kedacore/keda/issues/3787))
Expand Down
2 changes: 0 additions & 2 deletions pkg/scalers/couchdb_scaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,6 @@ func parseCouchDBMetadata(config *ScalerConfig) (*couchDBMetadata, string, error
} else {
// Build connection str
addr := net.JoinHostPort(meta.host, meta.port)
// addr := fmt.Sprintf("%s:%s", meta.host, meta.port)
// auth := fmt.Sprintf("%s:%s", meta.username, meta.password)
connStr = "http://" + addr
}
if val, ok := config.TriggerMetadata["metricName"]; ok {
Expand Down
4 changes: 2 additions & 2 deletions pkg/scalers/mongo_scaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net"
"net/url"
"strconv"
"time"

Expand Down Expand Up @@ -193,8 +194,7 @@ func parseMongoDBMetadata(config *ScalerConfig) (*mongoDBMetadata, string, error
} else {
// Build connection str
addr := net.JoinHostPort(meta.host, meta.port)
auth := fmt.Sprintf("%s:%s", meta.username, meta.password)
connStr = "mongodb://" + auth + "@" + addr + "/" + meta.dbName
connStr = fmt.Sprintf("mongodb://%s:%s@%s/%s", url.QueryEscape(meta.username), url.QueryEscape(meta.password), addr, meta.dbName)
}

if val, ok := config.TriggerMetadata["metricName"]; ok {
Expand Down
41 changes: 35 additions & 6 deletions pkg/scalers/mongo_scaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import (
"testing"

"github.com/go-logr/logr"
"github.com/stretchr/testify/assert"
"go.mongodb.org/mongo-driver/mongo"
)

var testMongoDBResolvedEnv = map[string]string{
"MongoDB_CONN_STR": "test_conn_str",
"MongoDB_PASSWORD": "test",
"MongoDB_CONN_STR": "mongodb://mongodb0.example.com:27017",
"MongoDB_PASSWORD": "test@password",
}

type parseMongoDBMetadataTestData struct {
Expand All @@ -20,6 +21,11 @@ type parseMongoDBMetadataTestData struct {
raisesError bool
}

type mongoDBConnectionStringTestData struct {
metadataTestData *parseMongoDBMetadataTestData
connectionString string
}

type mongoDBMetricIdentifier struct {
metadataTestData *parseMongoDBMetadataTestData
scalerIndex int
Expand All @@ -36,22 +42,29 @@ var testMONGODBMetadata = []parseMongoDBMetadataTestData{
},
// connectionStringFromEnv
{
metadata: map[string]string{"query": `{"name":"John"}`, "collection": "demo", "queryValue": "12", "connectionStringFromEnv": "Mongo_CONN_STR", "dbName": "test"},
metadata: map[string]string{"query": `{"name":"John"}`, "collection": "demo", "queryValue": "12", "connectionStringFromEnv": "MongoDB_CONN_STR", "dbName": "test"},
authParams: map[string]string{},
resolvedEnv: testMongoDBResolvedEnv,
raisesError: false,
},
// with metric name
{
metadata: map[string]string{"query": `{"name":"John"}`, "metricName": "hpa", "collection": "demo", "queryValue": "12", "connectionStringFromEnv": "Mongo_CONN_STR", "dbName": "test"},
metadata: map[string]string{"query": `{"name":"John"}`, "metricName": "hpa", "collection": "demo", "queryValue": "12", "connectionStringFromEnv": "MongoDB_CONN_STR", "dbName": "test"},
authParams: map[string]string{},
resolvedEnv: testMongoDBResolvedEnv,
raisesError: false,
},
// from passwordFromEnv
{
metadata: map[string]string{"query": `{"name":"John"}`, "metricName": "hpa", "collection": "demo", "queryValue": "12", "passwordFromEnv": "MongoDB_PASSWORD"},
authParams: map[string]string{"dbName": "test", "host": "localshot", "port": "1234", "username": "sample"},
resolvedEnv: testMongoDBResolvedEnv,
raisesError: false,
},
// from trigger auth
{
metadata: map[string]string{"query": `{"name":"John"}`, "metricName": "hpa", "collection": "demo", "queryValue": "12"},
authParams: map[string]string{"dbName": "test", "host": "localshot", "port": "1234", "username": "sample", "password": "secure"},
authParams: map[string]string{"dbName": "test", "host": "localshot", "port": "1234", "username": "sample", "password": "sec@ure"},
resolvedEnv: testMongoDBResolvedEnv,
raisesError: false,
},
Expand All @@ -64,14 +77,20 @@ var testMONGODBMetadata = []parseMongoDBMetadataTestData{
},
}

var mongoDBConnectionStringTestDatas = []mongoDBConnectionStringTestData{
{metadataTestData: &testMONGODBMetadata[2], connectionString: "mongodb://mongodb0.example.com:27017"},
{metadataTestData: &testMONGODBMetadata[3], connectionString: "mongodb://sample:test%40password@localshot:1234/test"},
{metadataTestData: &testMONGODBMetadata[4], connectionString: "mongodb://sample:sec%40ure@localshot:1234/test"},
}

var mongoDBMetricIdentifiers = []mongoDBMetricIdentifier{
{metadataTestData: &testMONGODBMetadata[2], scalerIndex: 0, name: "s0-mongodb-hpa"},
{metadataTestData: &testMONGODBMetadata[2], scalerIndex: 1, name: "s1-mongodb-hpa"},
}

func TestParseMongoDBMetadata(t *testing.T) {
for _, testData := range testMONGODBMetadata {
_, _, err := parseMongoDBMetadata(&ScalerConfig{TriggerMetadata: testData.metadata, AuthParams: testData.authParams})
_, _, err := parseMongoDBMetadata(&ScalerConfig{ResolvedEnv: testData.resolvedEnv, TriggerMetadata: testData.metadata, AuthParams: testData.authParams})
if err != nil && !testData.raisesError {
t.Error("Expected success but got error:", err)
}
Expand All @@ -81,6 +100,16 @@ func TestParseMongoDBMetadata(t *testing.T) {
}
}

func TestParseMongoDBConnectionString(t *testing.T) {
for _, testData := range mongoDBConnectionStringTestDatas {
_, connStr, err := parseMongoDBMetadata(&ScalerConfig{ResolvedEnv: testData.metadataTestData.resolvedEnv, TriggerMetadata: testData.metadataTestData.metadata, AuthParams: testData.metadataTestData.authParams})
if err != nil {
t.Error("Expected success but got error:", err)
}
assert.Equal(t, testData.connectionString, connStr)
}
}

func TestMongoDBGetMetricSpecForScaling(t *testing.T) {
for _, testData := range mongoDBMetricIdentifiers {
meta, _, err := parseMongoDBMetadata(&ScalerConfig{ResolvedEnv: testData.metadataTestData.resolvedEnv, AuthParams: testData.metadataTestData.authParams, TriggerMetadata: testData.metadataTestData.metadata, ScalerIndex: testData.scalerIndex})
Expand Down

0 comments on commit 3e40fc6

Please sign in to comment.