diff --git a/docker/scripts/setup.sh b/docker/scripts/setup.sh index c7a5dbdd8..6ccfac0d9 100755 --- a/docker/scripts/setup.sh +++ b/docker/scripts/setup.sh @@ -46,7 +46,8 @@ function cnf_servers() { "members": [ { "_id": 0, - "host": "${mongodb1}:${port}" + "host": "${mongodb1}:${port}", + "priority": 1000 }, { "_id": 1, @@ -77,7 +78,8 @@ function general_servers() { "members": [ { "_id": 0, - "host": "${mongodb1}:${port}" + "host": "${mongodb1}:${port}", + "priority": 1000 }, { "_id": 1, diff --git a/main.go b/main.go index 02bcbc01c..ec2c64d55 100644 --- a/main.go +++ b/main.go @@ -139,7 +139,7 @@ func main() { } func buildExporter(opts GlobalFlags, uri string, log *logrus.Logger) *exporter.Exporter { - uri = buildURI(uri, opts.User, opts.Password) + uri = buildURI(uri, opts.User, opts.Password, log) log.Debugf("Connection URI: %s", uri) uriParsed, _ := url.Parse(uri) @@ -266,26 +266,23 @@ func parseURIList(uriList []string, logger *logrus.Logger, splitCluster bool) [] return URIs } -func buildURI(uri string, user string, password string) string { - prefix := "mongodb://" // default prefix +func buildURI(uri string, user string, password string, log *logrus.Logger) string { + defaultPrefix := "mongodb://" // default prefix matchRegexp := regexp.MustCompile(`^mongodb(\+srv)?://`) - // Split the uri prefix if there is any - if matchRegexp.MatchString(uri) { - uriArray := strings.SplitN(uri, "://", 2) - prefix = uriArray[0] + "://" - uri = uriArray[1] + // Split the uri defaultPrefix if there is any + if !matchRegexp.MatchString(uri) { + uri = defaultPrefix + uri } - - // IF user@pass not contained in uri AND custom user and pass supplied in arguments - // DO concat a new uri with user and pass arguments value - if !strings.Contains(uri, "@") && user != "" && password != "" { - // add user and pass to the uri - uri = fmt.Sprintf("%s:%s@%s", user, password, uri) + parsedURI, err := url.Parse(uri) + if err != nil { + log.Fatalf("Failed to parse URI %s: %v", uri, err) + return uri } - // add back prefix after adding the user and pass - uri = prefix + uri + if parsedURI.User == nil && user != "" && password != "" { + parsedURI.User = url.UserPassword(user, password) + } - return uri + return parsedURI.String() } diff --git a/main_test.go b/main_test.go index b716a298c..0ab66bb46 100644 --- a/main_test.go +++ b/main_test.go @@ -219,12 +219,18 @@ func TestBuildURI(t *testing.T) { newPassword: "", expect: "mongodb+srv://xxx:zzz@127.0.0.1", }, + { + situation: "url with special characters in username and password", + origin: "mongodb://127.0.0.1", + newUser: "xxx?!#$%^&*()_+", + newPassword: "yyy?!#$%^&*()_+", + expect: "mongodb://xxx%3F%21%23$%25%5E&%2A%28%29_+:yyy%3F%21%23$%25%5E&%2A%28%29_+@127.0.0.1", + }, } for _, tc := range tests { - newUri := buildURI(tc.origin, tc.newUser, tc.newPassword) - // t.Logf("Origin: %s", tc.origin) - // t.Logf("Expect: %s", tc.expect) - // t.Logf("Result: %s", newUri) - assert.Equal(t, newUri, tc.expect) + t.Run(tc.situation, func(t *testing.T) { + newURI := buildURI(tc.origin, tc.newUser, tc.newPassword, logrus.New()) + assert.Equal(t, tc.expect, newURI) + }) } }