summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/puppet/provider/mysql_grant/mysql.rb148
1 files changed, 123 insertions, 25 deletions
diff --git a/lib/puppet/provider/mysql_grant/mysql.rb b/lib/puppet/provider/mysql_grant/mysql.rb
index 2c44e0b..d93b951 100644
--- a/lib/puppet/provider/mysql_grant/mysql.rb
+++ b/lib/puppet/provider/mysql_grant/mysql.rb
@@ -5,21 +5,48 @@
require 'puppet/provider/package'
-MYSQL_USER_PRIVS = [ :select_priv, :insert_priv, :update_priv, :delete_priv,
- :create_priv, :drop_priv, :reload_priv, :shutdown_priv, :process_priv,
- :file_priv, :grant_priv, :references_priv, :index_priv, :alter_priv,
- :show_db_priv, :super_priv, :create_tmp_table_priv, :lock_tables_priv,
- :execute_priv, :repl_slave_priv, :repl_client_priv, :create_view_priv,
- :show_view_priv, :create_routine_priv, :alter_routine_priv,
- :create_user_priv
+mysql_version = Facter.value(:mysql_version)
+if mysql_version =~ /^5.0/
+ MYSQL_USER_PRIVS = [ :select_priv, :insert_priv, :update_priv, :delete_priv,
+ :create_priv, :drop_priv, :reload_priv, :shutdown_priv, :process_priv,
+ :file_priv, :grant_priv, :references_priv, :index_priv, :alter_priv,
+ :show_db_priv, :super_priv, :create_tmp_table_priv, :lock_tables_priv,
+ :execute_priv, :repl_slave_priv, :repl_client_priv, :create_view_priv,
+ :show_view_priv, :create_routine_priv, :alter_routine_priv,
+ :create_user_priv
]
+else
+ MYSQL_USER_PRIVS = [ :select_priv, :insert_priv, :update_priv, :delete_priv,
+ :create_priv, :drop_priv, :reload_priv, :shutdown_priv, :process_priv,
+ :file_priv, :grant_priv, :references_priv, :index_priv, :alter_priv,
+ :show_db_priv, :super_priv, :create_tmp_table_priv, :lock_tables_priv,
+ :execute_priv, :repl_slave_priv, :repl_client_priv, :create_view_priv,
+ :show_view_priv, :create_routine_priv, :alter_routine_priv,
+ :create_user_priv, :trigger_priv
+ ]
+end
+
+if mysql_version =~ /^5.1/ && mysql_version.split('.').last.to_i >= 6
+ MYSQL_DB_PRIVS = [ :select_priv, :insert_priv, :update_priv, :delete_priv,
+ :create_priv, :drop_priv, :grant_priv, :references_priv, :index_priv,
+ :alter_priv, :create_tmp_table_priv, :lock_tables_priv, :create_view_priv,
+ :show_view_priv, :create_routine_priv, :alter_routine_priv, :execute_priv,
+ :event_priv, :trigger_priv
+ ]
+else
+ MYSQL_DB_PRIVS = [ :select_priv, :insert_priv, :update_priv, :delete_priv,
+ :create_priv, :drop_priv, :grant_priv, :references_priv, :index_priv,
+ :alter_priv, :create_tmp_table_priv, :lock_tables_priv, :create_view_priv,
+ :show_view_priv, :create_routine_priv, :alter_routine_priv, :execute_priv,
+ ]
+end
-MYSQL_DB_PRIVS = [ :select_priv, :insert_priv, :update_priv, :delete_priv,
- :create_priv, :drop_priv, :grant_priv, :references_priv, :index_priv,
- :alter_priv, :create_tmp_table_priv, :lock_tables_priv, :create_view_priv,
- :show_view_priv, :create_routine_priv, :alter_routine_priv, :execute_priv
+MYSQL_TABLE_PRIVS = [ :select, :insert, :update, :delete, :create, :drop,
+ :references, :index, :alter
]
+MYSQL_COLUMN_PRIVS = [ :select_priv, :insert_priv, :update_priv, :references_priv ]
+
Puppet::Type.type(:mysql_grant).provide(:mysql) do
desc "Uses mysql as database."
@@ -33,7 +60,8 @@ Puppet::Type.type(:mysql_grant).provide(:mysql) do
# this parses the
def split_name(string)
- matches = /^([^@]*)@([^\/]*)(\/(.*))?$/.match(string).captures.compact
+ matches = /^([^@]*)@([^\/]*)(\/([^\/]*))?(\/([^\/]*))?$/.match(string).captures.compact
+
case matches.length
when 2
{
@@ -48,6 +76,23 @@ Puppet::Type.type(:mysql_grant).provide(:mysql) do
:host => matches[1],
:db => matches[3]
}
+ when 6
+ {
+ :type => :tables_priv,
+ :user => matches[0],
+ :host => matches[1],
+ :db => matches[3],
+ :table_name => matches[5]
+ }
+ when 8
+ {
+ :type => :table,
+ :user => matches[0],
+ :host => matches[1],
+ :db => matches[3],
+ :table => matches[5],
+ :column => matches[7]
+ }
end
end
@@ -63,6 +108,10 @@ Puppet::Type.type(:mysql_grant).provide(:mysql) do
mysql "mysql", "-e", "INSERT INTO db (host, user, db) VALUES ('%s', '%s', '%s')" % [
name[:host], name[:user], name[:db],
]
+ when :column
+ mysql "mysql", "-e", "INSERT INTO columns_priv (host, user, db, table, column_name) VALUES ('%s', '%s', '%s', '%s', '%s')" % [
+ name[:host], name[:user], name[:db], name[:table], name[:column],
+ ]
end
mysql_flush
end
@@ -78,6 +127,9 @@ Puppet::Type.type(:mysql_grant).provide(:mysql) do
if name[:type] == :db
fields << :db
end
+ if name[:type] == :column
+ fields << :column
+ end
not mysql( "mysql", "-NBe", 'SELECT "1" FROM %s WHERE %s' % [ name[:type], fields.map do |f| "%s = '%s'" % [f, name[f]] end.join(' AND ')]).empty?
end
@@ -87,6 +139,10 @@ Puppet::Type.type(:mysql_grant).provide(:mysql) do
MYSQL_USER_PRIVS
when :db
MYSQL_DB_PRIVS
+ when :tables_priv
+ MYSQL_TABLE_PRIVS
+ when :column
+ MYSQL_COLUMN_PRIVS
end
all_privs = all_privs.collect do |p| p.to_s end.sort.join("|")
privs = privileges.collect do |p| p.to_s end.sort.join("|")
@@ -103,24 +159,36 @@ Puppet::Type.type(:mysql_grant).provide(:mysql) do
privs = mysql "mysql", "-Be", 'select * from user where user="%s" and host="%s"' % [ name[:user], name[:host] ]
when :db
privs = mysql "mysql", "-Be", 'select * from db where user="%s" and host="%s" and db="%s"' % [ name[:user], name[:host], name[:db] ]
+ when :tables_priv
+ privs = mysql "mysql", "-NBe", 'select Table_priv from tables_priv where User="%s" and Host="%s" and Db="%s" and Table_name="%s"' % [ name[:user], name[:host], name[:db], name[:table_name] ]
+ privs = privs.chomp.downcase
+ return privs
+ when :columns
+ privs = mysql "mysql", "-Be", 'select * from columns_priv where User="%s" and Host="%s" and Db="%s" and Table_name="%s" and Column_name="%s"' % [ name[:user], name[:host], name[:db], name[:table], name[:column] ]
end
if privs.match(/^$/)
privs = [] # no result, no privs
else
+ case name[:type]
+ when :user, :db
# returns a line with field names and a line with values, each tab-separated
- privs = privs.split(/\n/).map! do |l| l.chomp.split(/\t/) end
- # transpose the lines, so we have key/value pairs
- privs = privs[0].zip(privs[1])
- privs = privs.select do |p| p[0].match(/_priv$/) and p[1] == 'Y' end
+ privs = privs.split(/\n/).map! do |l| l.chomp.split(/\t/) end
+ # transpose the lines, so we have key/value pairs
+ privs = privs[0].zip(privs[1])
+ privs = privs.select do |p| (/_priv$/) and p[1] == 'Y' end
+ privs.collect do |p| symbolize(p[0].downcase) end
+ end
end
-
- privs.collect do |p| symbolize(p[0].downcase) end
end
def privileges=(privs)
- unless row_exists?
- create_row
+ name = split_name(@resource[:name])
+ # don't need to create a row for tables_priv and columns_priv
+ if name[:type] == :user || name[:type] == :db
+ unless row_exists?
+ create_row
+ end
end
# puts "Setting privs: ", privs.join(", ")
@@ -137,19 +205,49 @@ Puppet::Type.type(:mysql_grant).provide(:mysql) do
stmt = 'update db set '
where = ' where user="%s" and host="%s"' % [ name[:user], name[:host] ]
all_privs = MYSQL_DB_PRIVS
+ when :tables_priv
+ currently_set = privileges
+ currently_set = currently_set.scan(/\w+/)
+ privs.map! {|i| i.to_s.downcase}
+ revoke = currently_set - privs
+
+ if !revoke.empty?
+ #puts "Revoking table privs: ", revoke
+ mysql "mysql", "-e", "REVOKE %s ON %s.%s FROM '%s'@'%s'" % [ revoke.join(", "), name[:db], name[:table_name], name[:user], name[:host] ]
+ end
+
+ set = privs - currently_set
+ stmt = 'GRANT '
+ where = ' ON %s.%s TO "%s"@"%s"' % [ name[:db], name[:table_name], name[:user], name[:host] ]
+ all_privs = MYSQL_TABLE_PRIVS
+ when :column
+ stmt = 'update columns_priv set '
+ where = ' where user="%s" and host="%s" and Db="%s" and Table_name="%s"' % [ name[:user], name[:host], name[:db], name[:table_name] ]
+ all_privs = MYSQL_COLUMN_PRIVS
end
if privs[0] == :all
privs = all_privs
end
- # puts "stmt:", stmt
- set = all_privs.collect do |p| "%s = '%s'" % [p, privs.include?(p) ? 'Y' : 'N'] end.join(', ')
- # puts "set:", set
+ #puts "stmt:", stmt
+ case name[:type]
+ when :user
+ set = all_privs.collect do |p| "%s = '%s'" % [p, privs.include?(p) ? 'Y' : 'N'] end.join(', ')
+ when :db
+ set = all_privs.collect do |p| "%s = '%s'" % [p, privs.include?(p) ? 'Y' : 'N'] end.join(', ')
+ when :tables_priv
+ set = set.join(', ')
+ end
+
+ #puts "set:", set
stmt = stmt << set << where
+ #puts "stmt:", stmt
- mysql "mysql", "-Be", stmt
- mysql_flush
+ if !set.empty?
+ mysql "mysql", "-Be", stmt
+ mysql_flush
+ end
end
end