Skip to content

Commit bcad078

Browse files
author
Johan De Wit
committed
[authentication] No authentication possible when no user is yet created
1 parent 9fb9e9e commit bcad078

File tree

4 files changed

+28
-47
lines changed

4 files changed

+28
-47
lines changed

lib/puppet/provider/mongodb.rb

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -139,19 +139,13 @@ def self.db_ismaster
139139
cmd_ismaster = 'db.isMaster().ismaster'
140140
cmd_ismaster = mongoshrc_file + cmd_ismaster if mongoshrc_file
141141
db = 'admin'
142-
full_command = if mongoshrc_file
143-
mongoshrc_file + cmd_ismaster
144-
else
145-
cmd_ismaster
146-
end
147142

148143
begin
149144
res = mongosh_cmd(db, conn_string, cmd_ismaster).to_s.split(%r{\n}).last.chomp
150145
rescue StandardError => e
151-
if self.auth_enabled && e.message =~ %r{Authentication failed}
146+
if mongorc_file && res =~ %r{Authentication failed}
152147
res = mongosh_cmd(db, conn_string, 'db.isMaster().ismaster').to_s.chomp
153148
end
154-
end
155149

156150
res.eql?('true')
157151
end
@@ -187,6 +181,7 @@ def rs_initiated?
187181
def self.mongo_eval(cmd, db = 'admin', retries = 10, host = nil)
188182
retry_count = retries
189183
retry_sleep = 3
184+
no_auth_cmd = cmd
190185
cmd = mongoshrc_file + cmd if mongoshrc_file
191186

192187
out = nil
@@ -208,14 +203,14 @@ def self.mongo_eval(cmd, db = 'admin', retries = 10, host = nil)
208203
else
209204
retry_count -= 1
210205
if retry_count.positive?
211-
Puppet.debug "Request failed: '#{e.message}' Retry: '#{retries - retry_count}'"
212206
sleep retry_sleep
213207
retry
214208
end
215209
end
216210
end
217211

218-
raise Puppet::ExecutionFailure, "Could not evaluate MongoDB shell command: #{cmd}" unless out
212+
# return also the error message, so caller can react on it
213+
raise Puppet::ExecutionFailure, "Could not evaluate MongoDB shell command: #{cmd} with #{e.message}" unless out
219214

220215
Puppet::Util::MongodbOutput.sanitize(out)
221216
end

lib/puppet/provider/mongodb_database/mongodb.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ def self.instances
1616
new(name: db['name'],
1717
ensure: :present)
1818
end
19+
rescue => e
20+
Puppet.warning("Getting instances of mongodb_database failed: #{e}")
21+
[]
1922
end
2023

2124
# Assign prefetched dbs based on name.

lib/puppet/provider/mongodb_replset/mongo.rb

Lines changed: 20 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -131,65 +131,55 @@ def master_host(members)
131131

132132
def self.replset_properties
133133
conn_string = conn_string
134-
conn_string = conn_string # rubocop:disable Lint/SelfAssignment
135134
begin
136135
output = mongo_command('rs.conf()', conn_string)
136+
if output['members']
137+
return {
138+
name: output['_id'], # replica set name
139+
ensure: :present,
140+
members: output['members'],
141+
settings: output['settings'],
142+
provider: :mongo
143+
}
144+
end
145+
nil
137146
rescue Puppet::ExecutionFailure => e
138-
#if e.message =~ %r{command replSetGetConfig requires authentication} || e.message =~ %r{not authorized on admin to execute command} || e.message =~ %r{no replset config has been received}
139147
if e.message =~ %r{command replSetGetConfig requires authentication} || e.message =~ %r{not authorized on admin to execute command}
140-
Puppet.debug('XXXXXXXXX in replset_properties rescue part')
141148
output = mongo_command('rs.status()', conn_string)
142149
if output['members']
143150
memb = []
144151
output['members'].each do |m|
145152
memb << { 'host' => m['name'] }
146153
end
147-
{
154+
return {
148155
name: output['set'],
149156
ensure: :present,
150157
members: memb,
151-
#settings: @resource[:settings],
152158
provider: :mongo
153159
}
154160
end
155-
else
156161
nil
157162
end
158163
end
159-
if output['members']
160-
return {
161-
name: output['_id'], # replica set name
162-
ensure: :present,
163-
members: output['members'],
164-
settings: output['settings'],
165-
provider: :mongo
166-
}
167-
end
168-
nil
169164
end
170165

171166
def get_hosts_status(members)
172167
alive = []
173168
members.select do |member|
174169
host = member['host']
175-
Puppet.debug "Checking replicaset member #{host} ..."
176170
begin
177171
status = rs_status(host)
178-
Puppet.debug('XXXXXXXXXXXXXX should not get here since I dont have a replicaset')
179172
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'
180173

181174
if status.key?('set')
182175
raise Puppet::Error, "Can't configure replicaset #{name}, host #{host} is already part of another replicaset." if status['set'] != name
183176

184177
# This node is alive and supposed to be a member of our set
185-
Puppet.debug "Host #{host} is available for replset #{status['set']}"
186178
alive.push(member)
187179
elsif status.key?('info')
188-
Puppet.debug "Host #{host} is alive but unconfigured: #{status['info']}"
189180
alive.push(member)
190181
end
191182
rescue Puppet::ExecutionFailure => e
192-
Puppet.debug('XXXXXXXXXXXX in rescue checking connection mebers')
193183
if auth_enabled
194184
case e.message
195185
when %r{no replset config has been received}
@@ -258,26 +248,27 @@ def set_members
258248
return
259249
end
260250

261-
Puppet.debug 'Checking for dead and alive members'
251+
# When no replicaset is initiated yet, and authenticatoin is anabled,
252+
# mongo_eval still adds the mongorcsh.js. This gives an 'MongoServerError: Authentication failed.' error.
253+
# In this stage, we only can connect to localhost, and only rs.status() and rs.initiate() is possible.
254+
# All other commands generate 'MongoServerError: not authorized on admin to execute command' error
255+
# So we need to check first if the replicaset is already available, then the admin user can be created, and after that
256+
# authentication should be working.
257+
#
262258
if !@property_flush[:members].nil? && !@property_flush[:members].empty?
263259
# Find the alive members so we don't try to add dead members to the replset using new config
264260
alive_hosts, dead_hosts = get_hosts_status(@property_flush[:members])
265-
Puppet.debug "Alive members: #{alive_hosts.inspect}"
266-
Puppet.debug "Dead members: #{dead_hosts.inspect}" unless dead_hosts.empty?
267261
raise Puppet::Error, "Can't connect to any member of replicaset #{name}." if alive_hosts.empty?
268262
elsif !resource[:members].nil? && !resource[:members].empty?
269263
# Find the alive members using current 'is' config
270264
alive_hosts, dead_hosts = get_hosts_status(@resource[:members])
271-
Puppet.debug "Alive members: #{alive_hosts.inspect}"
272-
Puppet.debug "Dead members: #{dead_hosts.inspect}" unless dead_hosts.empty?
273265
raise Puppet::Error, "Can't connect to any member of replicaset #{name}." if alive_hosts.empty?
274266
else
275267
alive_hosts = []
276268
end
277269

278270
Puppet.debug 'Checking for new replset'
279271
if @property_flush[:ensure] == :present && @property_hash[:ensure] != :present && !master_host(alive_hosts)
280-
Puppet.debug "Initializing the replset #{name}"
281272

282273
# Create a replset configuration
283274
members_conf = alive_hosts.each_with_index.map do |host, id|
@@ -292,7 +283,6 @@ def set_members
292283
settings: (@property_flush[:settings].nil? ? {} : @property_flush[:settings])
293284
}.to_json
294285

295-
Puppet.debug "Starting replset config is #{replset_conf.to_json}"
296286
# Set replset members with the first host as the master
297287
output = rs_initiate(replset_conf, alive_hosts[0]['host'])
298288
raise Puppet::Error, "rs.initiate() failed for replicaset #{name}: #{output['errmsg']}" if output['ok'].zero?
@@ -303,25 +293,22 @@ def set_members
303293

304294
retry_limit.times do |n|
305295
if db_ismaster(alive_hosts[0]['host'])['ismaster']
306-
Puppet.debug 'Replica set initialization has successfully ended'
307296
return true
308297
else
309-
Puppet.debug "Wainting for replica initialization. Retry: #{n}"
298+
Puppet.debug "Waiting for replica initialization. Retry: #{n}"
310299
sleep retry_sleep
311300
next
312301
end
313302
end
314303
raise Puppet::Error, "rs.initiate() failed for replicaset #{name}: host #{alive_hosts[0]['host']} didn't become master"
315304

316305
else
317-
Puppet.debug "Checking for replset #{name} changes"
318306
master = master_host(alive_hosts)
319307
raise Puppet::Error, "Can't find master host for replicaset #{name}." unless master
320308

321309
master_rs_config = rs_config(master)
322310
add_members, remove_members, update_members = get_members_changes(master_rs_config['members'], @property_flush[:members])
323311

324-
Puppet.debug "Members to be Added: #{add_members.inspect}" unless add_members.empty?
325312
add_members.each do |member|
326313
retry_limit = 10
327314
retry_sleep = 3
@@ -330,18 +317,15 @@ def set_members
330317
retry_limit.times do |n|
331318
output = rs_add(member, master)
332319
if output['ok'].zero?
333-
Puppet.debug "Retry adding host to replicaset. Retry: #{n}"
334320
sleep retry_sleep
335321
master = master_host(alive_hosts)
336322
else
337-
Puppet.debug 'Host successfully added to replicaset'
338323
break
339324
end
340325
end
341326
raise Puppet::Error, "rs.add() failed to add host to replicaset #{name}: #{output['errmsg']}" if output['ok'].zero?
342327
end
343328

344-
Puppet.debug "Members to be Removed: #{remove_members.inspect}" unless remove_members.empty?
345329
remove_members.each do |member|
346330
retry_limit = 10
347331
retry_sleep = 3
@@ -350,18 +334,15 @@ def set_members
350334
retry_limit.times do |n|
351335
output = rs_remove(member, master)
352336
if output['ok'].zero?
353-
Puppet.debug "Retry removing host from replicaset. Retry: #{n}"
354337
sleep retry_sleep
355338
master = master_host(alive_hosts)
356339
else
357-
Puppet.debug 'Host successfully removed from replicaset'
358340
break
359341
end
360342
end
361343
raise Puppet::Error, "rs.remove() failed to remove host from replicaset #{name}: #{output['errmsg']}" if output['ok'].zero?
362344
end
363345

364-
Puppet.debug "Members to be Updated: #{update_members.inspect}" unless update_members.empty?
365346
update_members.each do |member|
366347
retry_limit = 10
367348
retry_sleep = 3
@@ -421,6 +402,7 @@ def self.mongo_command(command, host = nil, retries = 4)
421402
#end
422403

423404
# Hack to avoid non-json empty sets
405+
output = '{}' if output =~ %r{no replset config} || output =~ %r{Authentication failed}
424406
output = '{}' if output == "null\n"
425407
output = '{}' if output == "\nnull\n"
426408

lib/puppet/provider/mongodb_user/mongodb.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def self.prefetch(resources)
5555
mk_resource_methods
5656

5757
def create
58+
Puppet.debug("In mongodb_user.create. Only works when on the primery node")
5859
if db_ismaster
5960
password_hash = @resource[:password_hash]
6061
password_hash = Puppet::Util::MongodbMd5er.md5(@resource[:username], @resource[:password]) if !password_hash && @resource[:password]

0 commit comments

Comments
 (0)