Support DNS seedlist / `mongodb+srv://`
Mongo 3.6 adds support for using DNS SRV records to configure the initial set of ReplicaSet members instead of providing them in the connection string itself. See: https://docs.mongodb.com/manual/reference/connection-string/#dns-seedlist-connection-format and https://github.com/mongodb/specifications/blob/master/source/initial-dns-seedlist-discovery/initial-dns-seedlist-discovery.rst
It would be great to see support for this in mgo!
Hi @benweissmann
This sounds like a cool addition and should be relatively easy! We don't have a 3.6 testing environment built up yet but it's in the works, I'll leave this ticket open in the meantime.
Saying that, we'll happily accept a PR for this!
Dom
I forked but was not able to run unit tests b/c of the error below.
imports github.com/globalsign/mgo/internal/scram: use of internal package not allowed
Here are the changes to support dns seedlist :
$ git diff session.go
diff --git a/session.go b/session.go
index cd2a53e..488712f 100644
--- a/session.go
+++ b/session.go
@@ -788,7 +788,13 @@ type urlInfoOption struct {
}
func extractURL(s string) (*urlInfo, error) {
- s = strings.TrimPrefix(s, "mongodb://")
+ isSRV := false
+ if strings.Index(s, "mongodb+srv://") == 0 {
+ isSRV = true
+ s = strings.TrimPrefix(s, "mongodb+srv://")
+ } else {
+ s = strings.TrimPrefix(s, "mongodb://")
+ }
info := &urlInfo{options: []urlInfoOption{}}
if c := strings.Index(s, "?"); c != -1 {
@@ -824,6 +830,32 @@ func extractURL(s string) (*urlInfo, error) {
s = s[:c]
}
info.addrs = strings.Split(s, ",")
+ if isSRV == true {
+ // auto turn off ssl
+ info.options = append(info.options, urlInfoOption{key: "ssl", value: "true"})
+ srvAddr := info.addrs[0]
+ params, pe := net.LookupTXT(srvAddr)
+ if pe != nil {
+ return nil, fmt.Errorf(pe.Error())
+ }
+ for _, pair := range strings.FieldsFunc(params[0], isOptSep) {
+ l := strings.SplitN(pair, "=", 2)
+ if len(l) != 2 || l[0] == "" || l[1] == "" {
+ return nil, errors.New("connection option must be key=value: " + pair)
+ }
+ info.options = append(info.options, urlInfoOption{key: l[0], value: l[1]})
+ }
+ _, addrs, le := net.LookupSRV("mongodb", "tcp", srvAddr)
+ if le != nil {
+ return nil, fmt.Errorf(le.Error())
+ }
+ addresses := make([]string, len(addrs))
+ for i, addr := range addrs {
+ address := strings.TrimSuffix(addr.Target, ".")
+ addresses[i] = fmt.Sprintf("%s:%d", address, addr.Port)
+ }
+ info.addrs = addresses
+ }
return info, nil
}
@@ -2912,7 +2944,6 @@ func (p *Pipe) SetMaxTime(d time.Duration) *Pipe {
return p
}
This would make the MGO driver compatible with MongoDB Atlas
Any news?
It would really be great to see this implemented
I spent some time today porting the logic from the new, official Mongo driver back to mgo. We are running off of master, so I started my branch from there as it makes it easier for us to pick up without grabbing new features off of the development branch.
@maitesin I know that the contributions should be off of release. Before I send a PR over to you, does it have to be against development branch? While I know we are running against master, I don't know what most people are using. It is also unclear if/when a new release will be cut.
It's 2021, any updates on this issue?
Well, there now is an official Driver from MongoDB which also covers this use case.
I have switched to the official mongodb-go-driver. Here are some examples to help your transition, https://github.com/simagix/mongo-go-examples/tree/master/examples.
@ all: I wish you a Happy New Year 2022!
Any news about it?