globalsign / mgo

The MongoDB driver for Go
Other
1.97k stars 230 forks source link

Support DNS seedlist / `mongodb+srv://` #112

Open benweissmann opened 6 years ago

benweissmann commented 6 years ago

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!

domodwyer commented 6 years ago

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

simagix commented 6 years ago

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
 }
mhutter commented 5 years ago

This would make the MGO driver compatible with MongoDB Atlas

tnerolftnerolf commented 5 years ago

Any news?

frontmill commented 4 years ago

It would really be great to see this implemented

bonczj commented 4 years ago

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.

slaveofcode commented 3 years ago

It's 2021, any updates on this issue?

mhutter commented 3 years ago

Well, there now is an official Driver from MongoDB which also covers this use case.

simagix commented 3 years ago

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.

Neustradamus commented 2 years ago

@ all: I wish you a Happy New Year 2022!

Any news about it?