puppet-mongodb icon indicating copy to clipboard operation
puppet-mongodb copied to clipboard

Error: "Could not evaluate MongoDB shell: rs.slaveOk();printjson(db.getMongo().getDBs())" when auth = true

Open marcusphi opened this issue 5 years ago • 7 comments

Affected versions

  • Puppet: 6.10
  • Module version: 3.0.0

How to reproduce (e.g Puppet code you use)

  class {'::mongodb::server':
    storage_engine => 'wiredTiger',
    dbpath         => '/opt/mongodatafiles',
    dbpath_fix     => true,
    auth           => true,
    create_admin   => true,
    admin_username => 'admin',
    admin_password => 'secret123',
  }

Worth noting is that we have changed auth from false to true on an existing installation. I haven't tested a fresh installation with auth true. I have tested that the admin credentials still work after puppet run though.

After seeing https://forge.puppet.com/puppet/mongodb/readme#handle_creds I tried setting handle_creds => false but it didn't change anything. Do I really have to manage mongorc.js manually myself!?

Problem Description

Puppet log:

Error: Could not prefetch mongodb_database provider 'mongodb': Could not evaluate MongoDB shell command: rs.slaveOk();printjson(db.getMongo().getDBs())
Error: Failed to apply catalog: Could not evaluate MongoDB shell command: rs.slaveOk();printjson(db.getMongo().getDBs())

NB: This is even though we have no replicas and no mongodb_database or mongodb::db.

It seems here https://github.com/voxpupuli/puppet-mongodb/blob/v3.0.0/lib/puppet/provider/mongodb_database/mongodb.rb#L9 is where the call is made. I don't know Ruby well but I assume self.instances is invoked on some automatic instantiation even though we don't explicitly use it.

My guess is that #446 created this regression in combination with auth=true. It was noted by @Dharmender-Singh in the PR: https://github.com/voxpupuli/puppet-mongodb/pull/446#issuecomment-395127735 and I see no change in PR addressing this. But it seems weird that more people don't have this problem then...?

marcusphi avatar Nov 12 '19 10:11 marcusphi

It's possible that this is just lack of documentation...

marcusphi avatar Nov 12 '19 11:11 marcusphi

This code manifests/server/config.pp#L166 actually creates a mongorc.js file if all of handle_creds, auth and store_creds are true. I tested this now and it seems to work. It was a "documentation bug".

marcusphi avatar Nov 12 '19 11:11 marcusphi

It's these two that I think needs to be tweaked:

store_creds Store admin credentials in mongorc.js file. Uses with create_admin parameter

handle_creds Set this to false to avoid having puppet handle .mongorc.js in case you wish to deliver it by other means. This is needed for facts to work if you have auth set to true. Default is true.

Somewhere it should say explicitly that with auth and create_admin you need both of these true and that this will create a mongorc.js with authentication.

marcusphi avatar Nov 12 '19 11:11 marcusphi

As I said I don't know enough Ruby and Mongo to know for sure, but if it's the rs.slaveOk() part that fails and the db.getMongo().getDBs() would pass, one could probably do better in my case where there are no replicas and no usage of mongodb_database or mongodb::db.

marcusphi avatar Nov 12 '19 14:11 marcusphi

I'm having the same problem and it seems that puppet is trying to execute /usr/bin/mongo admin --quiet --host :27017 --eval ...., which leads to exception: Empty host component parsing HostAndPort from ":27017".

seidler2547 avatar Dec 05 '19 08:12 seidler2547

This happens all the time with this module and is some form of race condition. You have to turn auth off then complete a full puppet run to actually create the admin user then turn auth back on. The "localhost exception" could be used to deal with this : https://docs.mongodb.com/manual/core/security-users/#localhost-exception

whiphubley avatar Jan 08 '20 11:01 whiphubley

Please note this is still not fixed and the commit it issue 587 just attempts to handle the config file being in yaml. To clarify if you have auth enabled and have defined an admin user and password when you run puppet the following error occurs...

Error: Could not prefetch mongodb_database provider 'mongodb': Could not evaluate MongoDB shell command: load('/root/.mongorc.js'); try { rs.secondaryOk() } catch (err) { rs.slaveOk() };printjson(db.getMongo().getDBs()) Error: Failed to apply catalog: Could not evaluate MongoDB shell command: load('/root/.mongorc.js'); try { rs.secondaryOk() } catch (err) { rs.slaveOk() };printjson(db.getMongo().getDBs())

You have to disable auth and run puppet which is then able to create the admin user / db...

Notice: /Stage[main]/Mongodb::Server/Mongodb::Db[admin]/Mongodb_user[User admin on db admin]/ensure: created

And then you can finally re-enable authentication. There is clearly a race condition here which needs to be handled.

whiphubley avatar Jan 22 '24 15:01 whiphubley