Skip to content

Commit 0a03dbf

Browse files
Johan De Witstevenpost
authored andcommitted
Replace mongo shell with mongosh
Needed changes: - Use stderr for errors instead of stdout. The `mongo` command from the older client package put its errors on stout and exited with zero as exit code. Mongosh, by contrast, puts errors on stderr instead of stdout and exits with a non-zero exit code. This means we need to pass the underlying exception to the caller so it can deal with it appropriately. - Replace old functions: - `printjson` has become `EJSON.stringify`. - `rs.secondaryOk()` and `rs.slaveOk()` have become `db.getMongo().setReadPref("primaryPreferred")`. - `db` is now an object instead of the database name, we need to call `getName()` on it to get the database name. - Don't throw an exception from the `if (authRequired()) {` block, as that causes the `mongosh` command to stop processing further commands and exit with a non-zero exit code.
1 parent 320c82d commit 0a03dbf

File tree

23 files changed

+130
-114
lines changed

23 files changed

+130
-114
lines changed

REFERENCE.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ Data type: `String[1]`
6464

6565
Used to ensure that the package is installed, or that the package is absent/purged
6666

67-
Default value: `pick($mongodb::globals::version, 'present')`
67+
Default value: `pick($mongodb::globals::client_version, 'present')`
6868

6969
##### <a name="-mongodb--client--package_name"></a>`package_name`
7070

@@ -73,7 +73,7 @@ Data type: `String[1]`
7373
This setting can be used to specify the name of the package that should be installed.
7474
If not specified, the module will use whatever service name is the default for your OS distro.
7575

76-
Default value: `"mongodb-${mongodb::globals::edition}-shell"`
76+
Default value: `'mongodb-mongosh'`
7777

7878
### <a name="mongodb--globals"></a>`mongodb::globals`
7979

@@ -135,6 +135,7 @@ class {'mongodb::globals':
135135
The following parameters are available in the `mongodb::globals` class:
136136

137137
* [`version`](#-mongodb--globals--version)
138+
* [`client_version`](#-mongodb--globals--client_version)
138139
* [`manage_package_repo`](#-mongodb--globals--manage_package_repo)
139140
* [`repo_version`](#-mongodb--globals--repo_version)
140141
* [`use_enterprise_repo`](#-mongodb--globals--use_enterprise_repo)
@@ -153,6 +154,15 @@ If not specified, the module will ensure packages with `present`.
153154

154155
Default value: `undef`
155156

157+
##### <a name="-mongodb--globals--client_version"></a>`client_version`
158+
159+
Data type: `Optional[String[1]]`
160+
161+
The version of MongoDB Shell to install/manage.
162+
If not specified, the module will ensure packages with `present`.
163+
164+
Default value: `undef`
165+
156166
##### <a name="-mongodb--globals--manage_package_repo"></a>`manage_package_repo`
157167

158168
Data type: `Boolean`
@@ -967,7 +977,7 @@ Data type: `String`
967977

968978
The path to the custom mongosh rc file.
969979

970-
Default value: `"${facts['root_home']}/.mongorc.js"`
980+
Default value: `"${facts['root_home']}/.mongoshrc.js"`
971981

972982
##### <a name="-mongodb--server--service_manage"></a>`service_manage`
973983

lib/facter/is_master.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,16 @@ def get_options_from_config(file)
3939

4040
Facter.add('mongodb_is_master') do
4141
setcode do
42-
if %w[mongo mongod].all? { |m| Facter::Util::Resolution.which m }
42+
if %w[mongosh mongod].all? { |m| Facter::Util::Resolution.which m }
4343
file = mongod_conf_file
4444
if file
4545
options = get_options_from_config(file)
4646

4747
# Check if the mongodb server is responding:
48-
Facter::Core::Execution.exec("mongo --quiet #{options} --eval \"printjson(db.adminCommand({ ping: 1 }))\"")
48+
Facter::Core::Execution.exec("mongosh --quiet #{options} --eval \"EJSON.stringify(db.adminCommand({ ping: 1 }))\"")
4949

5050
if $CHILD_STATUS.success?
51-
Facter::Core::Execution.exec("mongo --quiet #{options} --eval \"db.isMaster().ismaster\"")
51+
Facter::Core::Execution.exec("mongosh --quiet #{options} --eval \"db.isMaster().ismaster\"")
5252
else
5353
'not_responding'
5454
end

lib/puppet/provider/mongodb.rb

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
class Puppet::Provider::Mongodb < Puppet::Provider
99
# Without initvars commands won't work.
1010
initvars
11-
commands mongo: 'mongo'
11+
commands mongosh: 'mongosh'
1212

1313
# Optional defaults file
14-
def self.mongorc_file
15-
"load('#{Facter.value(:root_home)}/.mongorc.js'); " if File.file?("#{Facter.value(:root_home)}/.mongorc.js")
14+
def self.mongoshrc_file
15+
"load('#{Facter.value(:root_home)}/.mongoshrc.js'); " if File.file?("#{Facter.value(:root_home)}/.mongoshrc.js")
1616
end
1717

18-
def mongorc_file
19-
self.class.mongorc_file
18+
def mongoshrc_file
19+
self.class.mongoshrc_file
2020
end
2121

2222
def self.mongod_conf_file
@@ -74,7 +74,7 @@ def self.tls_invalid_hostnames(config = nil)
7474
config['tlsallowInvalidHostnames']
7575
end
7676

77-
def self.mongo_cmd(db, host, cmd)
77+
def self.mongosh_cmd(db, host, cmd)
7878
config = mongo_conf
7979

8080
args = [db, '--quiet', '--host', host]
@@ -101,7 +101,7 @@ def self.mongo_cmd(db, host, cmd)
101101
end
102102

103103
args += ['--eval', cmd]
104-
mongo(args)
104+
mongosh(args)
105105
end
106106

107107
def self.conn_string
@@ -138,7 +138,7 @@ def self.conn_string
138138
def self.db_ismaster
139139
cmd_ismaster = 'db.isMaster().ismaster'
140140
db = 'admin'
141-
res = mongo_cmd(db, conn_string, cmd_ismaster).to_s.split(%r{\n}).last.chomp
141+
res = mongosh_cmd(db, conn_string, cmd_ismaster).to_s.split(%r{\n}).last.chomp
142142
res.eql?('true')
143143
end
144144

@@ -155,14 +155,14 @@ def self.auth_enabled(config = nil)
155155
def self.mongo_eval(cmd, db = 'admin', retries = 10, host = nil)
156156
retry_count = retries
157157
retry_sleep = 3
158-
cmd = mongorc_file + cmd if mongorc_file
158+
cmd = mongoshrc_file + cmd if mongoshrc_file
159159

160160
out = nil
161161
begin
162162
out = if host
163-
mongo_cmd(db, host, cmd)
163+
mongosh_cmd(db, host, cmd)
164164
else
165-
mongo_cmd(db, conn_string, cmd)
165+
mongosh_cmd(db, conn_string, cmd)
166166
end
167167
rescue StandardError => e
168168
retry_count -= 1
@@ -173,7 +173,7 @@ def self.mongo_eval(cmd, db = 'admin', retries = 10, host = nil)
173173
end
174174
end
175175

176-
raise Puppet::ExecutionFailure, "Could not evaluate MongoDB shell command: #{cmd}" unless out
176+
raise Puppet::ExecutionFailure, "Could not evaluate MongoDB shell command: #{cmd}, with: #{e.message}" unless out
177177

178178
Puppet::Util::MongodbOutput.sanitize(out)
179179
end

lib/puppet/provider/mongodb_database/mongodb.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
def self.instances
1010
require 'json'
1111

12-
pre_cmd = 'try { rs.secondaryOk() } catch (err) { rs.slaveOk() }'
13-
dbs = JSON.parse mongo_eval("#{pre_cmd};printjson(db.getMongo().getDBs())")
12+
pre_cmd = 'db.getMongo().setReadPref("primaryPreferred")'
13+
dbs = JSON.parse mongo_eval("#{pre_cmd};EJSON.stringify(db.getMongo().getDBs())")
1414

1515
dbs['databases'].map do |db|
1616
new(name: db['name'],

lib/puppet/provider/mongodb_replset/mongo.rb

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -153,31 +153,32 @@ def get_hosts_status(members)
153153
members.select do |member|
154154
host = member['host']
155155
Puppet.debug "Checking replicaset member #{host} ..."
156-
status = rs_status(host)
157-
raise Puppet::Error, "Can't configure replicaset #{name}, host #{host} is not supposed to be part of a replicaset." if status.key?('errmsg') && status['errmsg'] == 'not running with --replSet'
158-
159-
if auth_enabled && status.key?('errmsg') && (status['errmsg'].include?('unauthorized') || status['errmsg'].include?('not authorized') || status['errmsg'].include?('requires authentication'))
160-
Puppet.warning "Host #{host} is available, but you are unauthorized because of authentication is enabled: #{auth_enabled}"
161-
alive.push(member)
162-
end
163-
164-
if status.key?('errmsg') && status['errmsg'].include?('no replset config has been received')
165-
Puppet.debug 'Mongo v4 rs.status() RS not initialized output'
166-
alive.push(member)
167-
end
168-
169-
if status.key?('set')
170-
raise Puppet::Error, "Can't configure replicaset #{name}, host #{host} is already part of another replicaset." if status['set'] != name
171-
172-
# This node is alive and supposed to be a member of our set
173-
Puppet.debug "Host #{host} is available for replset #{status['set']}"
174-
alive.push(member)
175-
elsif status.key?('info')
176-
Puppet.debug "Host #{host} is alive but unconfigured: #{status['info']}"
177-
alive.push(member)
156+
begin
157+
status = rs_status(host)
158+
159+
if status.key?('set')
160+
raise Puppet::Error, "Can't configure replicaset #{name}, host #{host} is already part of another replicaset." if status['set'] != name
161+
162+
# This node is alive and supposed to be a member of our set
163+
Puppet.debug "Host #{host} is available for replset #{status['set']}"
164+
alive.push(member)
165+
elsif status.key?('info')
166+
Puppet.debug "Host #{host} is alive but unconfigured: #{status['info']}"
167+
alive.push(member)
168+
end
169+
rescue Puppet::ExecutionFailure => e
170+
raise Puppet::Error, "Can't configure replicaset #{name}, host #{host} is not supposed to be part of a replicaset." if e.message =~ %r{not running with --replSet}
171+
172+
if auth_enabled && (e.message.include?('unauthorized') || e.message.include?('not authorized') || e.message.include?('requires authentication'))
173+
Puppet.warning "Host #{host} is available, but you are unauthorized because of authentication is enabled: #{auth_enabled}"
174+
alive.push(member)
175+
elsif e.message.include?('no replset config has been received')
176+
Puppet.debug 'Mongo v4 rs.status() RS not initialized output'
177+
alive.push(member)
178+
else
179+
Puppet.warning "Can't connect to replicaset member #{host}."
180+
end
178181
end
179-
rescue Puppet::ExecutionFailure
180-
Puppet.warning "Can't connect to replicaset member #{host}."
181182
end
182183
alive.uniq!
183184
dead = members - alive
@@ -383,7 +384,7 @@ def mongo_command(command, host, retries = 4)
383384

384385
def self.mongo_command(command, host = nil, retries = 4)
385386
begin
386-
output = mongo_eval("printjson(#{command})", 'admin', retries, host)
387+
output = mongo_eval("EJSON.stringify(#{command})", 'admin', retries, host)
387388
rescue Puppet::ExecutionFailure => e
388389
Puppet.debug "Got an exception: #{e}"
389390
raise

lib/puppet/provider/mongodb_shard/mongo.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
mk_resource_methods
1515

16-
commands mongo: 'mongo'
16+
commands mongosh: 'mongosh'
1717

1818
def initialize(value = {})
1919
super(value)
@@ -152,8 +152,8 @@ def self.mongo_command(command, host = nil, _retries = 4)
152152
args = []
153153
args << '--quiet'
154154
args << ['--host', host] if host
155-
args << ['--eval', "printjson(#{command})"]
156-
output = mongo(args.flatten)
155+
args << ['--eval', "EJSON.stringify(#{command})"]
156+
output = mongosh(args.flatten)
157157
rescue Puppet::ExecutionFailure => e
158158
raise unless e =~ %r{Error: couldn't connect to server} && wait <= (2**max_wait)
159159

lib/puppet/provider/mongodb_user/mongodb.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,12 @@ def self.instances
1010
require 'json'
1111

1212
if db_ismaster
13-
script = 'printjson(db.system.users.find().toArray())'
13+
script = 'EJSON.stringify(db.system.users.find().toArray())'
1414
# A hack to prevent prefetching failures until admin user is created
15-
script = "try {#{script}} catch (e) { if (e.message.match(/not authorized on admin/)) { 'not authorized on admin' } else {throw e}}" if auth_enabled
15+
script = "try {#{script}} catch (e) { if (e.message.match(/requires authentication/) || e.message.match(/not authorized on admin/)) { 'not authorized on admin' } else {throw e}}" if auth_enabled
1616

1717
out = mongo_eval(script)
18-
19-
return [] if auth_enabled && out.include?('not authorized on admin')
18+
return [] if auth_enabled && (out.include?('requires authentication') || out.include?('not authorized on admin'))
2019

2120
users = JSON.parse out
2221

manifests/client.pp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
# If not specified, the module will use whatever service name is the default for your OS distro.
1212
#
1313
class mongodb::client (
14-
String[1] $ensure = pick($mongodb::globals::version, 'present'),
15-
String[1] $package_name = "mongodb-${mongodb::globals::edition}-shell",
14+
String[1] $ensure = pick($mongodb::globals::client_version, 'present'),
15+
String[1] $package_name = 'mongodb-mongosh',
1616
) inherits mongodb::globals {
1717
package { 'mongodb_client':
1818
ensure => $ensure,

manifests/globals.pp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@
4141
# The version of MonogDB to install/manage.
4242
# If not specified, the module will ensure packages with `present`.
4343
#
44+
# @param client_version
45+
# The version of MongoDB Shell to install/manage.
46+
# If not specified, the module will ensure packages with `present`.
47+
#
4448
# @param manage_package_repo
4549
# Whether to manage MongoDB software repository.
4650
#
@@ -71,6 +75,7 @@
7175
#
7276
class mongodb::globals (
7377
Optional[String[1]] $version = undef,
78+
Optional[String[1]] $client_version = undef,
7479
Boolean $manage_package_repo = true,
7580
String[1] $repo_version = '5.0',
7681
Boolean $use_enterprise_repo = false,

manifests/server.pp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@
328328
Optional[Stdlib::Absolutepath] $pidfilepath = undef,
329329
String[4,4] $pidfilemode = '0644',
330330
Boolean $manage_pidfile = false,
331-
String $rcfile = "${facts['root_home']}/.mongorc.js",
331+
String $rcfile = "${facts['root_home']}/.mongoshrc.js",
332332
Boolean $service_manage = true,
333333
Optional[String[1]] $service_provider = undef,
334334
String[1] $service_name = 'mongod',

0 commit comments

Comments
 (0)