diff --git a/models/agent_model.go b/models/agent_model.go index 9294da62eb..bc65b75bcd 100644 --- a/models/agent_model.go +++ b/models/agent_model.go @@ -442,13 +442,14 @@ func (s *Agent) DSN(service *Service, dialTimeout time.Duration, database string } switch { case password != "": - u.User = url.UserPassword(username, password) + u.User = url.UserPassword(username, "__password__") case username != "": u.User = url.User(username) } dsn := u.String() dsn = strings.ReplaceAll(dsn, url.QueryEscape(tdp.Left), tdp.Left) dsn = strings.ReplaceAll(dsn, url.QueryEscape(tdp.Right), tdp.Right) + dsn = strings.Replace(dsn, ":__password__@", ":"+url.QueryEscape(password)+"@", 1) return dsn case PostgresExporterType, QANPostgreSQLPgStatementsAgentType, QANPostgreSQLPgStatMonitorAgentType: diff --git a/models/agent_model_test.go b/models/agent_model_test.go index 32e2202e70..b8dc540534 100644 --- a/models/agent_model_test.go +++ b/models/agent_model_test.go @@ -61,8 +61,8 @@ func TestAgent(t *testing.T) { models.ProxySQLExporterType: "username:s3cur3 p@$$w0r4.@tcp(1.2.3.4:12345)/database?timeout=1s", models.QANMySQLPerfSchemaAgentType: "username:s3cur3 p@$$w0r4.@tcp(1.2.3.4:12345)/database?clientFoundRows=true&parseTime=true&timeout=1s", models.QANMySQLSlowlogAgentType: "username:s3cur3 p@$$w0r4.@tcp(1.2.3.4:12345)/database?clientFoundRows=true&parseTime=true&timeout=1s", - models.MongoDBExporterType: "mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/database?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", - models.QANMongoDBProfilerAgentType: "mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/database?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", + models.MongoDBExporterType: "mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:12345/database?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", + models.QANMongoDBProfilerAgentType: "mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:12345/database?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", models.PostgresExporterType: "postgres://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/database?connect_timeout=1&sslmode=disable", } { t.Run(string(typ), func(t *testing.T) { @@ -74,8 +74,15 @@ func TestAgent(t *testing.T) { t.Run("MongoDBNoDatabase", func(t *testing.T) { agent.AgentType = models.MongoDBExporterType - assert.Equal(t, "mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", agent.DSN(service, time.Second, "", nil)) - assert.Equal(t, "mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/", agent.DSN(service, 0, "", nil)) + assert.Equal(t, "mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:12345/?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", agent.DSN(service, time.Second, "", nil)) + assert.Equal(t, "mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:12345/", agent.DSN(service, 0, "", nil)) + }) + + t.Run("MongoDBPasswordContainsPlus", func(t *testing.T) { + agent.AgentType = models.MongoDBExporterType + agent.Password = pointer.ToString("s3cur3 p@$$w0r4." + "+" + ":__password__@") + + assert.Equal(t, "mongodb://username:s3cur3+p%40%24%24w0r4.%2B%3A__password__%40@1.2.3.4:12345/database?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", agent.DSN(service, time.Second, "database", nil)) }) }) @@ -109,8 +116,8 @@ func TestAgent(t *testing.T) { Socket: pointer.ToString("/var/run/mysqld/mysqld.sock"), } for typ, expected := range map[models.AgentType]string{ - models.MongoDBExporterType: "mongodb://username:s3cur3%20p%40$$w0r4.@%2Fvar%2Frun%2Fmysqld%2Fmysqld.sock/database?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", - models.QANMongoDBProfilerAgentType: "mongodb://username:s3cur3%20p%40$$w0r4.@%2Fvar%2Frun%2Fmysqld%2Fmysqld.sock/database?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", + models.MongoDBExporterType: "mongodb://username:s3cur3+p%40%24%24w0r4.@%2Fvar%2Frun%2Fmysqld%2Fmysqld.sock/database?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", + models.QANMongoDBProfilerAgentType: "mongodb://username:s3cur3+p%40%24%24w0r4.@%2Fvar%2Frun%2Fmysqld%2Fmysqld.sock/database?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", } { t.Run(string(typ), func(t *testing.T) { agent.AgentType = typ @@ -154,8 +161,8 @@ func TestAgent(t *testing.T) { models.ProxySQLExporterType: "username:s3cur3 p@$$w0r4.@tcp(1.2.3.4:12345)/database?timeout=1s&tls=true", models.QANMySQLPerfSchemaAgentType: "username:s3cur3 p@$$w0r4.@tcp(1.2.3.4:12345)/database?clientFoundRows=true&parseTime=true&timeout=1s&tls=custom", models.QANMySQLSlowlogAgentType: "username:s3cur3 p@$$w0r4.@tcp(1.2.3.4:12345)/database?clientFoundRows=true&parseTime=true&timeout=1s&tls=custom", - models.MongoDBExporterType: "mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/database?authMechanism=MONGODB-X509&connectTimeoutMS=1000&serverSelectionTimeoutMS=1000&ssl=true&tlsCaFile={{.TextFiles.caFilePlaceholder}}&tlsCertificateKeyFile={{.TextFiles.certificateKeyFilePlaceholder}}&tlsCertificateKeyFilePassword=pass", - models.QANMongoDBProfilerAgentType: "mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/database?authMechanism=MONGODB-X509&connectTimeoutMS=1000&serverSelectionTimeoutMS=1000&ssl=true&tlsCaFile={{.TextFiles.caFilePlaceholder}}&tlsCertificateKeyFile={{.TextFiles.certificateKeyFilePlaceholder}}&tlsCertificateKeyFilePassword=pass", + models.MongoDBExporterType: "mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:12345/database?authMechanism=MONGODB-X509&connectTimeoutMS=1000&serverSelectionTimeoutMS=1000&ssl=true&tlsCaFile={{.TextFiles.caFilePlaceholder}}&tlsCertificateKeyFile={{.TextFiles.certificateKeyFilePlaceholder}}&tlsCertificateKeyFilePassword=pass", + models.QANMongoDBProfilerAgentType: "mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:12345/database?authMechanism=MONGODB-X509&connectTimeoutMS=1000&serverSelectionTimeoutMS=1000&ssl=true&tlsCaFile={{.TextFiles.caFilePlaceholder}}&tlsCertificateKeyFile={{.TextFiles.certificateKeyFilePlaceholder}}&tlsCertificateKeyFilePassword=pass", models.PostgresExporterType: "postgres://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/database?connect_timeout=1&sslcert={{.TextFiles.certificateFilePlaceholder}}&sslkey={{.TextFiles.certificateKeyFilePlaceholder}}&sslmode=verify-ca&sslrootcert={{.TextFiles.caFilePlaceholder}}", } { t.Run(string(typ), func(t *testing.T) { @@ -171,8 +178,8 @@ func TestAgent(t *testing.T) { agent.MongoDBOptions.TLSCertificateKeyFilePassword = "" agent.MongoDBOptions.AuthenticationMechanism = "" - assert.Equal(t, "mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000&ssl=true&tlsCaFile={{.TextFiles.caFilePlaceholder}}&tlsCertificateKeyFile={{.TextFiles.certificateKeyFilePlaceholder}}", agent.DSN(service, time.Second, "", nil)) - assert.Equal(t, "mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/?ssl=true&tlsCaFile={{.TextFiles.caFilePlaceholder}}&tlsCertificateKeyFile={{.TextFiles.certificateKeyFilePlaceholder}}", agent.DSN(service, 0, "", nil)) + assert.Equal(t, "mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:12345/?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000&ssl=true&tlsCaFile={{.TextFiles.caFilePlaceholder}}&tlsCertificateKeyFile={{.TextFiles.certificateKeyFilePlaceholder}}", agent.DSN(service, time.Second, "", nil)) + assert.Equal(t, "mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:12345/?ssl=true&tlsCaFile={{.TextFiles.caFilePlaceholder}}&tlsCertificateKeyFile={{.TextFiles.certificateKeyFilePlaceholder}}", agent.DSN(service, 0, "", nil)) expectedFiles := map[string]string{ "caFilePlaceholder": "cert", "certificateKeyFilePlaceholder": "key", @@ -187,8 +194,8 @@ func TestAgent(t *testing.T) { agent.MongoDBOptions.AuthenticationMechanism = "MONGO-X509" agent.MongoDBOptions.AuthenticationDatabase = "$external" - assert.Equal(t, "mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/?authMechanism=MONGO-X509&authSource=%24external&connectTimeoutMS=1000&serverSelectionTimeoutMS=1000&ssl=true&tlsCaFile={{.TextFiles.caFilePlaceholder}}&tlsCertificateKeyFile={{.TextFiles.certificateKeyFilePlaceholder}}", agent.DSN(service, time.Second, "", nil)) - assert.Equal(t, "mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/?authMechanism=MONGO-X509&authSource=%24external&ssl=true&tlsCaFile={{.TextFiles.caFilePlaceholder}}&tlsCertificateKeyFile={{.TextFiles.certificateKeyFilePlaceholder}}", agent.DSN(service, 0, "", nil)) + assert.Equal(t, "mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:12345/?authMechanism=MONGO-X509&authSource=%24external&connectTimeoutMS=1000&serverSelectionTimeoutMS=1000&ssl=true&tlsCaFile={{.TextFiles.caFilePlaceholder}}&tlsCertificateKeyFile={{.TextFiles.certificateKeyFilePlaceholder}}", agent.DSN(service, time.Second, "", nil)) + assert.Equal(t, "mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:12345/?authMechanism=MONGO-X509&authSource=%24external&ssl=true&tlsCaFile={{.TextFiles.caFilePlaceholder}}&tlsCertificateKeyFile={{.TextFiles.certificateKeyFilePlaceholder}}", agent.DSN(service, 0, "", nil)) expectedFiles := map[string]string{ "caFilePlaceholder": "cert", "certificateKeyFilePlaceholder": "key", @@ -213,8 +220,8 @@ func TestAgent(t *testing.T) { models.ProxySQLExporterType: "username:s3cur3 p@$$w0r4.@tcp(1.2.3.4:12345)/database?timeout=1s&tls=skip-verify", models.QANMySQLPerfSchemaAgentType: "username:s3cur3 p@$$w0r4.@tcp(1.2.3.4:12345)/database?clientFoundRows=true&parseTime=true&timeout=1s&tls=skip-verify", models.QANMySQLSlowlogAgentType: "username:s3cur3 p@$$w0r4.@tcp(1.2.3.4:12345)/database?clientFoundRows=true&parseTime=true&timeout=1s&tls=skip-verify", - models.MongoDBExporterType: "mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/database?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000&ssl=true&tlsInsecure=true", - models.QANMongoDBProfilerAgentType: "mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/database?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000&ssl=true&tlsInsecure=true", + models.MongoDBExporterType: "mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:12345/database?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000&ssl=true&tlsInsecure=true", + models.QANMongoDBProfilerAgentType: "mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:12345/database?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000&ssl=true&tlsInsecure=true", models.PostgresExporterType: "postgres://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/database?connect_timeout=1&sslmode=require", } { t.Run(string(typ), func(t *testing.T) { @@ -226,8 +233,8 @@ func TestAgent(t *testing.T) { t.Run("MongoDBNoDatabase", func(t *testing.T) { agent.AgentType = models.MongoDBExporterType - assert.Equal(t, "mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000&ssl=true&tlsInsecure=true", agent.DSN(service, time.Second, "", nil)) - assert.Equal(t, "mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:12345/?ssl=true&tlsInsecure=true", agent.DSN(service, 0, "", nil)) + assert.Equal(t, "mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:12345/?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000&ssl=true&tlsInsecure=true", agent.DSN(service, time.Second, "", nil)) + assert.Equal(t, "mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:12345/?ssl=true&tlsInsecure=true", agent.DSN(service, 0, "", nil)) }) }) } diff --git a/services/agents/mongodb_test.go b/services/agents/mongodb_test.go index 902ccd87da..5271e88163 100644 --- a/services/agents/mongodb_test.go +++ b/services/agents/mongodb_test.go @@ -55,7 +55,7 @@ func TestMongodbExporterConfig225(t *testing.T) { "--web.listen-address=:{{ .listen_port }}", }, Env: []string{ - "MONGODB_URI=mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:27017/?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", + "MONGODB_URI=mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:27017/?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", "HTTP_AUTH=pmm:agent-password", }, RedactWords: []string{"s3cur3 p@$$w0r4.", "agent-password"}, @@ -113,7 +113,7 @@ func TestMongodbExporterConfig226(t *testing.T) { "--web.listen-address=:{{ .listen_port }}", }, Env: []string{ - "MONGODB_URI=mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:27017/?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", + "MONGODB_URI=mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:27017/?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", "HTTP_AUTH=pmm:agent-password", }, RedactWords: []string{"s3cur3 p@$$w0r4.", "agent-password"}, @@ -256,7 +256,7 @@ func TestMongodbExporterConfig(t *testing.T) { "--web.listen-address=:{{ .listen_port }}", }, Env: []string{ - "MONGODB_URI=mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:27017/?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", + "MONGODB_URI=mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:27017/?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", "HTTP_AUTH=pmm:agent-password", }, RedactWords: []string{"s3cur3 p@$$w0r4.", "agent-password"}, @@ -369,7 +369,7 @@ func TestNewMongodbExporterConfig(t *testing.T) { "--web.listen-address=:{{ .listen_port }}", }, Env: []string{ - "MONGODB_URI=mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:27017/?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", + "MONGODB_URI=mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:27017/?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", "HTTP_AUTH=pmm:agent-id", }, RedactWords: []string{"s3cur3 p@$$w0r4."}, @@ -421,7 +421,7 @@ func TestMongodbExporterConfig228_WebConfigAuth(t *testing.T) { } expectedEnv := []string{ - "MONGODB_URI=mongodb://username:s3cur3%20p%40$$w0r4.@1.2.3.4:27017/?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", + "MONGODB_URI=mongodb://username:s3cur3+p%40%24%24w0r4.@1.2.3.4:27017/?connectTimeoutMS=1000&serverSelectionTimeoutMS=1000", } t.Run("Custom_Password", func(t *testing.T) {