puppet-mongodb
puppet-mongodb copied to clipboard
Error: "Could not evaluate MongoDB shell: rs.slaveOk();printjson(db.getMongo().getDBs())" when auth = true
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...?
It's possible that this is just lack of documentation...
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".
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.
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.
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"
.
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
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.