Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Patch providers for absent my.cnf #141

Merged
merged 3 commits into from
Jan 11, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions lib/puppet/provider/database/mysql.rb
Original file line number Original file line Diff line number Diff line change
@@ -1,42 +1,52 @@
Puppet::Type.type(:database).provide(:mysql) do Puppet::Type.type(:database).provide(:mysql) do

desc "Manages MySQL database." desc "Manages MySQL database."


defaultfor :kernel => 'Linux' defaultfor :kernel => 'Linux'


optional_commands :mysql => 'mysql' optional_commands :mysql => 'mysql'
optional_commands :mysqladmin => 'mysqladmin' optional_commands :mysqladmin => 'mysqladmin'


def self.defaults_file
if File.file?("#{Facter.value(:root_home)}/.my.cnf")
"--defaults-file=#{Facter.value(:root_home)}/.my.cnf"
else
nil
end
end

def defaults_file
self.class.defaults_file
end

def self.instances def self.instances
mysql("--defaults-file=#{Facter.value(:root_home)}/.my.cnf", '-NBe', "show databases").split("\n").collect do |name| mysql([defaults_file, '-NBe', "show databases"].compact).split("\n").collect do |name|
new(:name => name) new(:name => name)
end end
end end


def create def create
mysql("--defaults-file=#{Facter.value(:root_home)}/.my.cnf", '-NBe', "create database `#{@resource[:name]}` character set #{resource[:charset]}") mysql([defaults_file, '-NBe', "create database `#{@resource[:name]}` character set #{resource[:charset]}"].compact)
end end


def destroy def destroy
mysqladmin("--defaults-file=#{Facter.value(:root_home)}/.my.cnf", '-f', 'drop', @resource[:name]) mysqladmin([defaults_file, '-f', 'drop', @resource[:name]].compact)
end end


def charset def charset
mysql("--defaults-file=#{Facter.value(:root_home)}/.my.cnf", '-NBe', "show create database `#{resource[:name]}`").match(/.*?(\S+)\s(?:COLLATE.*)?\*\//)[1] mysql([defaults_file, '-NBe', "show create database `#{resource[:name]}`"].compact).match(/.*?(\S+)\s(?:COLLATE.*)?\*\//)[1]
end end


def charset=(value) def charset=(value)
mysql("--defaults-file=#{Facter.value(:root_home)}/.my.cnf", '-NBe', "alter database `#{resource[:name]}` CHARACTER SET #{value}") mysql([defaults_file, '-NBe', "alter database `#{resource[:name]}` CHARACTER SET #{value}"].compact)
end end


def exists? def exists?
begin begin
mysql("--defaults-file=#{Facter.value(:root_home)}/.my.cnf", '-NBe', "show databases").match(/^#{@resource[:name]}$/) mysql([defaults_file, '-NBe', "show databases"].compact).match(/^#{@resource[:name]}$/)
rescue => e rescue => e
debug(e.message) debug(e.message)
return nil return nil
end end
end end


end end

36 changes: 24 additions & 12 deletions lib/puppet/provider/database_grant/mysql.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -34,19 +34,19 @@ def db_privs
end end


def self.query_user_privs def self.query_user_privs
results = mysql("--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "mysql", "-Be", "describe user") results = mysql([defaults_file, "mysql", "-Be", "describe user"].compact)
column_names = results.split(/\n/).map { |l| l.chomp.split(/\t/)[0] } column_names = results.split(/\n/).map { |l| l.chomp.split(/\t/)[0] }
@user_privs = column_names.delete_if { |e| !( e =~/_priv$/) } @user_privs = column_names.delete_if { |e| !( e =~/_priv$/) }
end end


def self.query_db_privs def self.query_db_privs
results = mysql("--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "mysql", "-Be", "describe db") results = mysql([defaults_file, "mysql", "-Be", "describe db"].compact)
column_names = results.split(/\n/).map { |l| l.chomp.split(/\t/)[0] } column_names = results.split(/\n/).map { |l| l.chomp.split(/\t/)[0] }
@db_privs = column_names.delete_if { |e| !(e =~/_priv$/) } @db_privs = column_names.delete_if { |e| !(e =~/_priv$/) }
end end


def mysql_flush def mysql_flush
mysqladmin "--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "flush-privileges" mysqladmin([defaults_file, "flush-privileges"].compact)
end end


# this parses the # this parses the
Expand Down Expand Up @@ -74,20 +74,20 @@ def create_row
name = split_name(@resource[:name]) name = split_name(@resource[:name])
case name[:type] case name[:type]
when :user when :user
mysql "--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "mysql", "-e", "INSERT INTO user (host, user) VALUES ('%s', '%s')" % [ mysql([defaults_file, "mysql", "-e", "INSERT INTO user (host, user) VALUES ('%s', '%s')" % [
name[:host], name[:user], name[:host], name[:user],
] ]].compact)
when :db when :db
mysql "--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "mysql", "-e", "INSERT INTO db (host, user, db) VALUES ('%s', '%s', '%s')" % [ mysql([defaults_file, "mysql", "-e", "INSERT INTO db (host, user, db) VALUES ('%s', '%s', '%s')" % [
name[:host], name[:user], name[:db], name[:host], name[:user], name[:db],
] ]].compact)
end end
mysql_flush mysql_flush
end end
end end


def destroy def destroy
mysql "--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "mysql", "-e", "REVOKE ALL ON '%s'.* FROM '%s@%s'" % [ @resource[:privileges], @resource[:database], @resource[:name], @resource[:host] ] mysql([defaults_file, "mysql", "-e", "REVOKE ALL ON '%s'.* FROM '%s@%s'" % [ @resource[:privileges], @resource[:database], @resource[:name], @resource[:host] ]].compact)
end end


def row_exists? def row_exists?
Expand All @@ -96,7 +96,7 @@ def row_exists?
if name[:type] == :db if name[:type] == :db
fields << :db fields << :db
end end
not mysql("--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "mysql", '-NBe', 'SELECT "1" FROM %s WHERE %s' % [ name[:type], fields.map do |f| "%s=\"%s\"" % [f, name[f]] end.join(' AND ')]).empty? not mysql([defaults_file, "mysql", '-NBe', 'SELECT "1" FROM %s WHERE %s' % [ name[:type], fields.map do |f| "%s=\"%s\"" % [f, name[f]] end.join(' AND ')]].compact).empty?
end end


def all_privs_set? def all_privs_set?
Expand All @@ -118,9 +118,9 @@ def privileges


case name[:type] case name[:type]
when :user when :user
privs = mysql "--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "mysql", "-Be", 'select * from mysql.user where user="%s" and host="%s"' % [ name[:user], name[:host] ] privs = mysql([defaults_file, "mysql", "-Be", 'select * from mysql.user where user="%s" and host="%s"' % [ name[:user], name[:host] ]].compact)
when :db when :db
privs = mysql "--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "mysql", "-Be", 'select * from mysql.db where user="%s" and host="%s" and db="%s"' % [ name[:user], name[:host], name[:db] ] privs = mysql([defaults_file, "mysql", "-Be", 'select * from mysql.db where user="%s" and host="%s" and db="%s"' % [ name[:user], name[:host], name[:db] ]].compact)
end end


if privs.match(/^$/) if privs.match(/^$/)
Expand Down Expand Up @@ -172,7 +172,7 @@ def privileges=(privs)
stmt = stmt << set << where stmt = stmt << set << where


validate_privs privs, all_privs validate_privs privs, all_privs
mysql "--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "mysql", "-Be", stmt mysql([defaults_file, "mysql", "-Be", stmt].compact)
mysql_flush mysql_flush
end end


Expand All @@ -195,4 +195,16 @@ def validate_privs(set_privs, all_privs)
end end
end end


# Optional defaults file
def self.defaults_file
if File.file?("#{Facter.value(:root_home)}/.my.cnf")
"--defaults-file=#{Facter.value(:root_home)}/.my.cnf"
else
nil
end
end
def defaults_file
self.class.defaults_file
end

end end
26 changes: 19 additions & 7 deletions lib/puppet/provider/database_user/mysql.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -8,35 +8,47 @@
optional_commands :mysqladmin => 'mysqladmin' optional_commands :mysqladmin => 'mysqladmin'


def self.instances def self.instances
users = mysql("--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "mysql", '-BNe' "select concat(User, '@',Host) as User from mysql.user").split("\n") users = mysql([defaults_file, "mysql", '-BNe' "select concat(User, '@',Host) as User from mysql.user"].compact).split("\n")
users.select{ |user| user =~ /.+@/ }.collect do |name| users.select{ |user| user =~ /.+@/ }.collect do |name|
new(:name => name) new(:name => name)
end end
end end


def create def create
mysql("--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "mysql", "-e", "create user '%s' identified by PASSWORD '%s'" % [ @resource[:name].sub("@", "'@'"), @resource.value(:password_hash) ]) mysql([defaults_file, "mysql", "-e", "create user '%s' identified by PASSWORD '%s'" % [ @resource[:name].sub("@", "'@'"), @resource.value(:password_hash) ]].compact)
end end


def destroy def destroy
mysql("--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "mysql", "-e", "drop user '%s'" % @resource.value(:name).sub("@", "'@'") ) mysql([defaults_file, "mysql", "-e", "drop user '%s'" % @resource.value(:name).sub("@", "'@'") ].compact)
end end


def password_hash def password_hash
mysql("--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "mysql", "-NBe", "select password from mysql.user where CONCAT(user, '@', host) = '%s'" % @resource.value(:name)).chomp mysql([defaults_file, "mysql", "-NBe", "select password from mysql.user where CONCAT(user, '@', host) = '%s'" % @resource.value(:name)].compact).chomp
end end


def password_hash=(string) def password_hash=(string)
mysql("--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "mysql", "-e", "SET PASSWORD FOR '%s' = '%s'" % [ @resource[:name].sub("@", "'@'"), string ] ) mysql([defaults_file, "mysql", "-e", "SET PASSWORD FOR '%s' = '%s'" % [ @resource[:name].sub("@", "'@'"), string ] ].compact)
end end


def exists? def exists?
not mysql("--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "mysql", "-NBe", "select '1' from mysql.user where CONCAT(user, '@', host) = '%s'" % @resource.value(:name)).empty? not mysql([defaults_file, "mysql", "-NBe", "select '1' from mysql.user where CONCAT(user, '@', host) = '%s'" % @resource.value(:name)].compact).empty?
end end


def flush def flush
@property_hash.clear @property_hash.clear
mysqladmin "--defaults-file=#{Facter.value(:root_home)}/.my.cnf", "flush-privileges" mysqladmin([defaults_file, "flush-privileges"].compact)
end

# Optional defaults file
def self.defaults_file
if File.file?("#{Facter.value(:root_home)}/.my.cnf")
"--defaults-file=#{Facter.value(:root_home)}/.my.cnf"
else
nil
end
end
def defaults_file
self.class.defaults_file
end end


end end
37 changes: 23 additions & 14 deletions spec/unit/puppet/provider/database_grant/mysql_spec.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@
) )
@provider = provider_class.new(@resource) @provider = provider_class.new(@resource)
Facter.stubs(:value).with(:root_home).returns(root_home) Facter.stubs(:value).with(:root_home).returns(root_home)
File.stubs(:file?).with("#{root_home}/.my.cnf").returns(true)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There aren't any tests checking for the CONVERSE behavior (where --defaults-file wasn't being called). We should at least test that behavior.

end end


it 'should query privilegess from the database' do it 'should query privilegess from the database' do
provider_class.expects(:mysql) .with("--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', 'describe user').returns <<-EOT provider_class.expects(:mysql) .with(["--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', 'describe user']).returns <<-EOT
Field Type Null Key Default Extra Field Type Null Key Default Extra
Host char(60) NO PRI Host char(60) NO PRI
User char(16) NO PRI User char(16) NO PRI
Expand All @@ -26,7 +27,7 @@
Insert_priv enum('N','Y') NO N Insert_priv enum('N','Y') NO N
Update_priv enum('N','Y') NO N Update_priv enum('N','Y') NO N
EOT EOT
provider_class.expects(:mysql).with("--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', 'describe db').returns <<-EOT provider_class.expects(:mysql).with(["--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', 'describe db']).returns <<-EOT
Field Type Null Key Default Extra Field Type Null Key Default Extra
Host char(60) NO PRI Host char(60) NO PRI
Db char(64) NO PRI Db char(64) NO PRI
Expand All @@ -40,47 +41,55 @@
end end


it 'should query set priviliges' do it 'should query set priviliges' do
provider_class.expects(:mysql).with("--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', 'select * from mysql.user where user="user" and host="host"').returns <<-EOT provider_class.expects(:mysql).with(["--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', 'select * from mysql.user where user="user" and host="host"']).returns <<-EOT
Host User Password Select_priv Insert_priv Update_priv Host User Password Select_priv Insert_priv Update_priv
host user Y N Y host user Y N Y
EOT EOT
@provider.privileges.should == [ 'Select_priv', 'Update_priv' ] @provider.privileges.should == [ 'Select_priv', 'Update_priv' ]
end end


it 'should recognize when all priviliges are set' do it 'should recognize when all priviliges are set' do
provider_class.expects(:mysql).with("--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', 'select * from mysql.user where user="user" and host="host"').returns <<-EOT provider_class.expects(:mysql).with(["--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', 'select * from mysql.user where user="user" and host="host"']).returns <<-EOT
Host User Password Select_priv Insert_priv Update_priv Host User Password Select_priv Insert_priv Update_priv
host user Y Y Y host user Y Y Y
EOT EOT
@provider.all_privs_set?.should == true @provider.all_privs_set?.should == true
end end


it 'should recognize when all privileges are not set' do it 'should recognize when all privileges are not set' do
provider_class.expects(:mysql).with("--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', 'select * from mysql.user where user="user" and host="host"').returns <<-EOT provider_class.expects(:mysql).with(["--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', 'select * from mysql.user where user="user" and host="host"']).returns <<-EOT
Host User Password Select_priv Insert_priv Update_priv Host User Password Select_priv Insert_priv Update_priv
host user Y N Y host user Y N Y
EOT EOT
@provider.all_privs_set?.should == false @provider.all_privs_set?.should == false
end end


it 'should be able to set all privileges' do it 'should be able to set all privileges' do
provider_class.expects(:mysql).with("--defaults-file=#{root_home}/.my.cnf", 'mysql', '-NBe', 'SELECT "1" FROM user WHERE user="user" AND host="host"').returns "1\n" provider_class.expects(:mysql).with(["--defaults-file=#{root_home}/.my.cnf", 'mysql', '-NBe', 'SELECT "1" FROM user WHERE user="user" AND host="host"']).returns "1\n"
provider_class.expects(:mysql).with("--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', "update user set Select_priv = 'Y', Insert_priv = 'Y', Update_priv = 'Y' where user=\"user\" and host=\"host\"") provider_class.expects(:mysql).with(["--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', "update user set Select_priv = 'Y', Insert_priv = 'Y', Update_priv = 'Y' where user=\"user\" and host=\"host\""])
provider_class.expects(:mysqladmin).with("--defaults-file=#{root_home}/.my.cnf", "flush-privileges") provider_class.expects(:mysqladmin).with(["--defaults-file=#{root_home}/.my.cnf", "flush-privileges"])
@provider.privileges=(['all']) @provider.privileges=(['all'])
end end


it 'should be able to set partial privileges' do it 'should be able to set partial privileges' do
provider_class.expects(:mysql).with("--defaults-file=#{root_home}/.my.cnf", 'mysql', '-NBe', 'SELECT "1" FROM user WHERE user="user" AND host="host"').returns "1\n" provider_class.expects(:mysql).with(["--defaults-file=#{root_home}/.my.cnf", 'mysql', '-NBe', 'SELECT "1" FROM user WHERE user="user" AND host="host"']).returns "1\n"
provider_class.expects(:mysql).with("--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', "update user set Select_priv = 'Y', Insert_priv = 'N', Update_priv = 'Y' where user=\"user\" and host=\"host\"") provider_class.expects(:mysql).with(["--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', "update user set Select_priv = 'Y', Insert_priv = 'N', Update_priv = 'Y' where user=\"user\" and host=\"host\""])
provider_class.expects(:mysqladmin).with("--defaults-file=#{root_home}/.my.cnf", "flush-privileges") provider_class.expects(:mysqladmin).with(["--defaults-file=#{root_home}/.my.cnf", "flush-privileges"])
@provider.privileges=(['Select_priv', 'Update_priv']) @provider.privileges=(['Select_priv', 'Update_priv'])
end end


it 'should be case insensitive' do it 'should be case insensitive' do
provider_class.expects(:mysql).with("--defaults-file=#{root_home}/.my.cnf", 'mysql', '-NBe', 'SELECT "1" FROM user WHERE user="user" AND host="host"').returns "1\n" provider_class.expects(:mysql).with(["--defaults-file=#{root_home}/.my.cnf", 'mysql', '-NBe', 'SELECT "1" FROM user WHERE user="user" AND host="host"']).returns "1\n"
provider_class.expects(:mysql).with("--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', "update user set Select_priv = 'Y', Insert_priv = 'Y', Update_priv = 'Y' where user=\"user\" and host=\"host\"") provider_class.expects(:mysql).with(["--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', "update user set Select_priv = 'Y', Insert_priv = 'Y', Update_priv = 'Y' where user=\"user\" and host=\"host\""])
provider_class.expects(:mysqladmin).with("--defaults-file=#{root_home}/.my.cnf", 'flush-privileges') provider_class.expects(:mysqladmin).with(["--defaults-file=#{root_home}/.my.cnf", 'flush-privileges'])
@provider.privileges=(['SELECT_PRIV', 'insert_priv', 'UpDaTe_pRiV']) @provider.privileges=(['SELECT_PRIV', 'insert_priv', 'UpDaTe_pRiV'])
end end

it 'should not pass --defaults-file if $root_home/.my.cnf is absent' do
File.stubs(:file?).with("#{root_home}/.my.cnf").returns(false)
provider_class.expects(:mysql).with(['mysql', '-NBe', 'SELECT "1" FROM user WHERE user="user" AND host="host"']).returns "1\n"
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\""])
provider_class.expects(:mysqladmin).with(["flush-privileges"])
@provider.privileges=(['Select_priv', 'Update_priv'])
end
end end