Skip to content

Commit 3cfbb58

Browse files
committed
Change grant provider to ignore grants for non existing users.
In the grant provider users are fetched by querying mysql.user table. Grants for those users are fetched using show grants for... syntax. This can lead to errors, when some of the users in mysql.user table do not have currently active grants. This happens at least when MySQL is started with --skip-name-resolve option, when there are users with the hostname part specified as a FQDN. Such users are created by mysql_install_db. This leads to problems if mysql::account_security is included for the node and skip-name-resolve is specified in override_options hash for mysql::server. Includes acceptance test for the change.
1 parent 4f4c687 commit 3cfbb58

File tree

2 files changed

+92
-1
lines changed

2 files changed

+92
-1
lines changed

lib/puppet/provider/mysql_grant/mysql.rb

+14-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,20 @@ def self.instances
88
users.select{ |user| user =~ /.+@/ }.collect do |user|
99
user_string = self.cmd_user(user)
1010
query = "SHOW GRANTS FOR #{user_string};"
11-
grants = mysql([defaults_file, "-NBe", query].compact)
11+
begin
12+
grants = mysql([defaults_file, "-NBe", query].compact)
13+
rescue Puppet::ExecutionFailure => e
14+
# Silently ignore users with no grants. Can happen e.g. if user is
15+
# defined with fqdn and server is run with skip-name-resolve. Example:
16+
# Default root user created by mysql_install_db on a host with fqdn
17+
# of myhost.mydomain.my: [email protected], when MySQL is started
18+
# with --skip-name-resolve.
19+
if e.inspect =~ /There is no such grant defined for user/
20+
next
21+
else
22+
raise Puppet::Error, "#mysql had an error -> #{e.inspect}"
23+
end
24+
end
1225
# Once we have the list of grants generate entries for each.
1326
grants.each_line do |grant|
1427
# Match the munges we do in the type.

spec/acceptance/types/mysql_grant_spec.rb

+78
Original file line numberDiff line numberDiff line change
@@ -320,4 +320,82 @@ class { 'mysql::server': }
320320
end
321321
end
322322
end
323+
324+
describe 'grants with skip-name-resolve specified' do
325+
it 'setup mysql::server' do
326+
pp = <<-EOS
327+
class { 'mysql::server':
328+
override_options => {
329+
'mysqld' => {'skip-name-resolve' => true}
330+
},
331+
restart => true,
332+
}
333+
EOS
334+
335+
apply_manifest(pp, :catch_failures => true)
336+
end
337+
338+
it 'should apply' do
339+
pp = <<-EOS
340+
mysql_grant { '[email protected]/test.*':
341+
ensure => 'present',
342+
table => 'test.*',
343+
user => '[email protected]',
344+
privileges => 'ALL',
345+
}
346+
mysql_grant { '[email protected]/test.*':
347+
ensure => 'present',
348+
table => 'test.*',
349+
user => '[email protected]',
350+
privileges => 'ALL',
351+
}
352+
EOS
353+
354+
apply_manifest(pp, :catch_failures => true)
355+
end
356+
357+
it 'should have skip_name_resolve set' do
358+
shell("mysql -NBe 'select @@skip_name_resolve'") do |r|
359+
expect(r.stdout).to match(/1/)
360+
expect(r.stderr).to be_empty
361+
end
362+
end
363+
364+
it 'should fail with fqdn' do
365+
expect(shell("mysql -NBe \"SHOW GRANTS FOR [email protected]\"", { :acceptable_exit_codes => 1}).stderr).to match(/There is no such grant defined for user 'test' on host 'fqdn.com'/)
366+
end
367+
it 'finds ipv4' do
368+
shell("mysql -NBe \"SHOW GRANTS FOR 'test'@'192.168.5.7'\"") do |r|
369+
expect(r.stdout).to match(/GRANT ALL PRIVILEGES ON `test`.* TO 'test'@'192.168.5.7'/)
370+
expect(r.stderr).to be_empty
371+
end
372+
end
373+
374+
it 'should fail to execute while applying' do
375+
pp = <<-EOS
376+
mysql_grant { '[email protected]/test.*':
377+
ensure => 'present',
378+
table => 'test.*',
379+
user => '[email protected]',
380+
privileges => 'ALL',
381+
}
382+
EOS
383+
384+
mysql_cmd = shell('which mysql').stdout.chomp
385+
shell("mv #{mysql_cmd} #{mysql_cmd}.bak")
386+
expect(apply_manifest(pp, :expect_failures => true).stderr).to match(/Command mysql is missing/)
387+
shell("mv #{mysql_cmd}.bak #{mysql_cmd}")
388+
end
389+
390+
it 'reset mysql::server config' do
391+
pp = <<-EOS
392+
class { 'mysql::server':
393+
restart => true,
394+
}
395+
EOS
396+
397+
apply_manifest(pp, :catch_failures => true)
398+
end
399+
end
400+
323401
end

0 commit comments

Comments
 (0)