mongodb-haskell/mongodb

Can't connect to atlas

glensargent opened this issue · 19 comments

Following the example provided in this report, I'm attempting to connect to my Atlas cluster:

main :: IO ()
main = do
    pipe <- connect (host mongoHost)
    e <- access pipe master databaseName allCollections
    close pipe
    print e

However, I'm receiving this error: Network.BSD.getHostByName: does not exist (no such host entry)

It's worth noting that I'm passing the mongo uri to the connect function (+srv), is utilising the mongo uri not supported by this library? If not, would it be possible for someone to provide an example of how to connect to a remote atlas cluster? Again, if not supported, I'd love to request that this gets supported since Mongo URI's are the standard connect / host strings for all official drivers

Cheers!

I've dug around all over the place and I'm really struggling to find any simple examples of how to successfully connect, I've yet to find anyone succeed beyond hardcoding (or cluster api request) their node hosts

Hey @glensargent I am using Mongo Atlas and have been doing so for years. Please don't consider this as perfect Haskell but this is how an old project of mine (still running!) connects: https://github.com/why-not-try-calmer/feedo/blob/c5ba378eb64c66ebf5842a371293fb5f0cdb163b/src/Mongo.hs#L70-L136. The last 2 functions in the snippet are those that matter.

sorry in advance if there are better channels for this, but any updates on whether this driver plans to properly support connecting to atlas and it's use cases?

sorry in advance if there are better channels for this, but any updates on whether this
driver plans to properly support connecting to atlas and it's use cases?

Hi Glen, I cannot speak for the maintainer-(s?) of this repository but from my experience using the library and interacting with people here, chances are low. That's because:

  • Mongo Atlas is a proprietary codebase and service we have no control over, meaning they can make server-side changes that we can at best guess through tests;
  • Mongo Atlas didn't exist when this library was written, and given the previous point, I can understand if it never was considered a priority as far as developing or maintaining the library is concerned

What I would suggest is to try and use one of the (ideally dockerized) versions of Mongo DB: the community edition is free, uses a reasonable license and better matches the specification that people who wrote this library had in mind.

That's a shame, I'm a heavy user of atlas at work, we have databases that have tens of thousands of read and writes per second and the only reason I'm not using haskell for any production services at my job is because it can not connect to atlas at all - I think that will probably be the same for other people that are users of mongo for high traffic services / distributed systems

That's a shame, I'm a heavy user of atlas at work, we have databases that have tens of thousands of read and writes per second and the only reason I'm not using haskell for any production services at my job is because it can not connect to atlas at all - I think that will probably be the same for other people that are users of mongo for high traffic services / distributed systems

I used to be able to use Mongo Atlas flawlessly in Haskell until they introduced a breaking change some one year ago. We managed to work with a Mongo employee to solve it server-side but apparently it broke again. If I could find time to investigate I would.

I'll see if I can find any old contacts from MongoDB. Can't promise anything though.

I'll see if I can find any old contacts from MongoDB. Can't promise anything though.

That'd be amazing! I'll also mention it to our mongo manager when we speak next

Hi @VictorDenisov, I am a maintainer of https://github.com/mongodb/mongo-java-driver and would be happy to assist you with anything you need.

Hi @jyemin. Thanks for offering help. We could definitely use some insight into atlas auth protocol. Are there any docs for it? Maybe you could point us to java code that does atlas authentication?

Hi @VictorDenisov no worries. Happy to help. So there may be a misconception here: there are no Atlas-only authentication mechanisms, it's just that there are some that are easier to enable on the server if you're using Atlas (e.g. MONGODB-AWS). For the most common ones, e.g. SCRAM-SHA-*, you should be able to test easily without relying on Atlas.

For good reference material, all the drivers implement to a common auth specification, which you can find here: https://github.com/mongodb/specifications/blob/master/source/auth/auth.md.

In fact, pretty much every facet of the driver is specified in https://github.com/mongodb/specifications, including a unified test runner.

Happy to point you at Java (or any other language) driver code for anything specific you have questions on.

It looks like you can connect to Atlas, but the srv URIs are not working. I'm able to connect like this:

main :: IO ()
main = do
  repSet <- openReplicaSetSRV' "cluster0.abcdxyz.mongodb.net"
  p <- primary repSet
  is_auth <- access p master "admin" $ auth "username" "password"
  unless is_auth (throwIO $ userError "Authentication failed!")

  e <- access p master "baseball" run
  print e

Full code.

If your full Atlas URI is mongodb+srv://adriandole:password@cluster0.abcdxyz.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0 you should use just cluster0.abcdxyz.mongodb.net part.

It looks like you can connect to Atlas, but the srv URIs are not working. I'm able to connect like this:

main :: IO ()
main = do
  repSet <- openReplicaSetSRV' "cluster0.abcdxyz.mongodb.net"
  p <- primary repSet
  is_auth <- access p master "admin" $ auth "username" "password"
  unless is_auth (throwIO $ userError "Authentication failed!")

  e <- access p master "baseball" run
  print e

Full code.

If your full Atlas URI is mongodb+srv://adriandole:password@cluster0.abcdxyz.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0 you should use just cluster0.abcdxyz.mongodb.net part.

This works for me! Thanks so much. Are there any technical implications in connecting this way since it isn't the recommended way of connecting, or would this be fine in production? Looks to me like it's just slightly less abstract but otherwise more or less the same?

It's fine to connect this way. The Haskell driver does what it's supposed to as far as discovering your nodes, but currently has some limitations in URI parsing that this fix avoids.

Thanks so much. @VictorDenisov does it make sense to patch the connect function to check for this? I'm happy to be the one to take a look, might have a few questions as I go though

Do you mean you want to patch it to parse URIs?

Yeah, only if that aligns with the behaviour you think it should have

openReplicaSetSRV' accepts a hostname as its argument. If you want a function that accepts a connect string I think it should be a separate function. Like connectURI or something like that. It can parse the URI and invoke lower level functions for connecting. A PR would be greatly appreciated for sure!

I'll close this issue for now since it's been resolved, thanks team :)