Skip to content

Commit 3fbb54d

Browse files
committed
Merge pull request #65 from branan/14218_query_db_for_permissions
Query the database for possible permissions
2 parents e6b45eb + 29cef3f commit 3fbb54d

File tree

3 files changed

+113
-27
lines changed

3 files changed

+113
-27
lines changed

lib/puppet/provider/database_grant/mysql.rb

+38-20
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,6 @@
33
# user@host => global
44
# user@host/db => per-db
55

6-
MYSQL_USER_PRIVS = [ :select_priv, :insert_priv, :update_priv, :delete_priv,
7-
:create_priv, :drop_priv, :reload_priv, :shutdown_priv, :process_priv,
8-
:file_priv, :grant_priv, :references_priv, :index_priv, :alter_priv,
9-
:show_db_priv, :super_priv, :create_tmp_table_priv, :lock_tables_priv,
10-
:execute_priv, :repl_slave_priv, :repl_client_priv, :create_view_priv,
11-
:show_view_priv, :create_routine_priv, :alter_routine_priv,
12-
:create_user_priv, :event_priv, :trigger_priv
13-
]
14-
15-
MYSQL_DB_PRIVS = [ :select_priv, :insert_priv, :update_priv, :delete_priv,
16-
:create_priv, :drop_priv, :grant_priv, :references_priv, :index_priv,
17-
:alter_priv, :create_tmp_table_priv, :lock_tables_priv, :create_view_priv,
18-
:show_view_priv, :create_routine_priv, :alter_routine_priv, :execute_priv
19-
]
20-
216
Puppet::Type.type(:database_grant).provide(:mysql) do
227

238
desc "Uses mysql as database."
@@ -27,6 +12,39 @@
2712
optional_commands :mysql => 'mysql'
2813
optional_commands :mysqladmin => 'mysqladmin'
2914

15+
def self.prefetch(resources)
16+
@user_privs = query_user_privs
17+
@db_privs = query_db_privs
18+
end
19+
20+
def self.user_privs
21+
@user_privs || query_user_privs
22+
end
23+
24+
def self.db_privs
25+
@db_privs || query_db_privs
26+
end
27+
28+
def user_privs
29+
self.class.user_privs
30+
end
31+
32+
def db_privs
33+
self.class.db_privs
34+
end
35+
36+
def self.query_user_privs
37+
results = mysql("mysql", "-Be", "describe user")
38+
column_names = results.split(/\n/).map { |l| l.chomp.split(/\t/)[0] }
39+
@user_privs = column_names.delete_if { |e| !( e =~/_priv$/) }.map! { |p| p.intern }
40+
end
41+
42+
def self.query_db_privs
43+
results = mysql("mysql", "-Be", "describe db")
44+
column_names = results.split(/\n/).map { |l| l.chomp.split(/\t/)[0] }
45+
@db_privs = column_names.delete_if { |e| !(e =~/_priv$/) }.map! { |p| p.intern }
46+
end
47+
3048
def mysql_flush
3149
mysqladmin "flush-privileges"
3250
end
@@ -84,9 +102,9 @@ def row_exists?
84102
def all_privs_set?
85103
all_privs = case split_name(@resource[:name])[:type]
86104
when :user
87-
MYSQL_USER_PRIVS
105+
user_privs
88106
when :db
89-
MYSQL_DB_PRIVS
107+
db_privs
90108
end
91109
all_privs = all_privs.collect do |p| p.to_s end.sort.join("|")
92110
privs = privileges.collect do |p| p.to_s end.sort.join("|")
@@ -115,7 +133,7 @@ def privileges
115133
privs = privs.select do |p| p[0].match(/_priv$/) and p[1] == 'Y' end
116134
end
117135

118-
privs.collect do |p| symbolize(p[0].downcase) end
136+
privs.collect do |p| symbolize(p[0]) end
119137
end
120138

121139
def privileges=(privs)
@@ -132,11 +150,11 @@ def privileges=(privs)
132150
when :user
133151
stmt = 'update user set '
134152
where = ' where user="%s" and host="%s"' % [ name[:user], name[:host] ]
135-
all_privs = MYSQL_USER_PRIVS
153+
all_privs = user_privs
136154
when :db
137155
stmt = 'update db set '
138156
where = ' where user="%s" and host="%s"' % [ name[:user], name[:host] ]
139-
all_privs = MYSQL_DB_PRIVS
157+
all_privs = db_privs
140158
end
141159

142160
if privs[0] == :all

manifests/db.pp

+1-7
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,6 @@
3838
$enforce_sql = false
3939
) {
4040

41-
if $grant == 'all' {
42-
$safe_grant = [ 'alter_priv', 'alter_routine_priv', 'create_priv', 'create_routine_priv', 'create_tmp_table_priv', 'create_view_priv', 'delete_priv', 'drop_priv', 'event_priv', 'execute_priv', 'grant_priv', 'index_priv', 'insert_priv', 'lock_tables_priv', 'references_priv', 'select_priv', 'show_view_priv', 'trigger_priv', 'update_priv']
43-
} else {
44-
$safe_grant = $grant
45-
}
46-
4741
database { $name:
4842
ensure => present,
4943
charset => $charset,
@@ -59,7 +53,7 @@
5953
}
6054

6155
database_grant { "${user}@${host}/${name}":
62-
privileges => $safe_grant,
56+
privileges => $grant,
6357
provider => 'mysql',
6458
require => Database_user["${user}@${host}"],
6559
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
require 'puppet'
2+
require 'mocha'
3+
RSpec.configure do |config|
4+
config.mock_with :mocha
5+
end
6+
provider_class = Puppet::Type.type(:database_grant).provider(:mysql)
7+
describe provider_class do
8+
before :each do
9+
@resource = Puppet::Type::Database_grant.new(
10+
{ :privileges => 'all"', :provider => 'mysql', :name => 'user@host'}
11+
)
12+
@provider = provider_class.new(@resource)
13+
end
14+
it 'should query privilegess from the database' do
15+
provider_class.expects(:mysql) .with('mysql', '-Be', 'describe user').returns <<-EOT
16+
Field Type Null Key Default Extra
17+
Host char(60) NO PRI
18+
User char(16) NO PRI
19+
Password char(41) NO
20+
Select_priv enum('N','Y') NO N
21+
Insert_priv enum('N','Y') NO N
22+
Update_priv enum('N','Y') NO N
23+
EOT
24+
provider_class.expects(:mysql).with('mysql', '-Be', 'describe db').returns <<-EOT
25+
Field Type Null Key Default Extra
26+
Host char(60) NO PRI
27+
Db char(64) NO PRI
28+
User char(16) NO PRI
29+
Select_priv enum('N','Y') NO N
30+
Insert_priv enum('N','Y') NO N
31+
Update_priv enum('N','Y') NO N
32+
EOT
33+
provider_class.user_privs.should == [ :Select_priv, :Insert_priv, :Update_priv ]
34+
provider_class.db_privs.should == [ :Select_priv, :Insert_priv, :Update_priv ]
35+
end
36+
37+
it 'should query set priviliges' do
38+
provider_class.expects(:mysql).with('mysql', '-Be', 'select * from user where user="user" and host="host"').returns <<-EOT
39+
Host User Password Select_priv Insert_priv Update_priv
40+
host user Y N Y
41+
EOT
42+
@provider.privileges.should == [ :Select_priv, :Update_priv ]
43+
end
44+
45+
it 'should recognize when all priviliges are set' do
46+
provider_class.expects(:mysql).with('mysql', '-Be', 'select * from user where user="user" and host="host"').returns <<-EOT
47+
Host User Password Select_priv Insert_priv Update_priv
48+
host user Y Y Y
49+
EOT
50+
@provider.all_privs_set?.should == true
51+
end
52+
53+
it 'should recognize when all privileges are not set' do
54+
provider_class.expects(:mysql).with('mysql', '-Be', 'select * from user where user="user" and host="host"').returns <<-EOT
55+
Host User Password Select_priv Insert_priv Update_priv
56+
host user Y N Y
57+
EOT
58+
@provider.all_privs_set?.should == false
59+
end
60+
61+
it 'should be able to set all privileges' do
62+
provider_class.expects(:mysql).with('mysql', '-NBe', 'SELECT "1" FROM user WHERE user = \'user\' AND host = \'host\'').returns "1\n"
63+
provider_class.expects(:mysql).with('mysql', '-Be', "update user set Select_priv = 'Y', Insert_priv = 'Y', Update_priv = 'Y' where user=\"user\" and host=\"host\"")
64+
provider_class.expects(:mysqladmin).with("flush-privileges")
65+
@provider.privileges=([:all])
66+
end
67+
68+
it 'should be able to set partial privileges' do
69+
provider_class.expects(:mysql).with('mysql', '-NBe', 'SELECT "1" FROM user WHERE user = \'user\' AND host = \'host\'').returns "1\n"
70+
provider_class.expects(:mysql).with('mysql', '-Be', "update user set Select_priv = 'Y', Insert_priv = 'N', Update_priv = 'Y' where user=\"user\" and host=\"host\"")
71+
provider_class.expects(:mysqladmin).with("flush-privileges")
72+
@provider.privileges=([:Select_priv, :Update_priv])
73+
end
74+
end

0 commit comments

Comments
 (0)