]> gitweb.fluxo.info Git - puppet-mysql.git/commitdiff
Updating mysql_grant provider with changes from the shared/riseup mysql module
authorSilvio Rhatto <rhatto@riseup.net>
Sat, 26 Jan 2013 14:54:05 +0000 (12:54 -0200)
committerSilvio Rhatto <rhatto@riseup.net>
Sat, 26 Jan 2013 14:54:05 +0000 (12:54 -0200)
lib/puppet/provider/mysql_grant/mysql.rb

index 2c44e0bc52dc208f0fd1a248170995bf9975af85..d93b951681092786da61b9e8bea947864a348527 100644 (file)
@@ -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