Skip to content

Commit

Permalink
Merge branch 'master' into test
Browse files Browse the repository at this point in the history
Conflicts:
	lib/puppet/provider/mysql_database/mysql.rb
	lib/puppet/provider/mysql_grant/mysql.rb
	lib/puppet/provider/mysql_user/mysql.rb
	manifests/server.pp
  • Loading branch information
gnarf committed Oct 4, 2012
2 parents d136568 + ada37f1 commit 19d7eed
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 53 deletions.
43 changes: 32 additions & 11 deletions lib/puppet/provider/mysql_database/mysql.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,38 @@
require 'puppet/provider/package'
# -*- tab-width: 4; ruby-indent-level: 4; indent-tabs-mode: t -*-
Puppet::Type.type(:mysql_database).provide :mysql, :parent => Puppet::Provider::Package do
desc "Provide MySQL interactions via /usr/bin/mysql"

Puppet::Type.type(:mysql_database).provide(:mysql,
:parent => Puppet::Provider::Package) do
# this is a bit of a hack.
# Since puppet evaluates what provider to use at start time rather than run time
# we can't specify that commands will exist. Instead we call manually.
# I would make these call execute directly, but execpipe needs the path
def self.mysqladmin
'/usr/bin/mysqladmin'
end
def self.mysql
'/usr/bin/mysql'
end
def mysqladmin
self.class.mysqladmin
end
def mysql
self.class.mysql
end

desc "Use mysql as database."
commands :mysqladmin => 'HOME="/root" /usr/bin/mysqladmin'
commands :mysql => 'HOME="/root" /usr/bin/mysql'
def execute_home(command, options = {})
default_options = {
:custom_environment => {}
}
options = default_options.merge(options)
options[:custom_environment][:HOME] = '/root'
execute(command, options)
end

# retrieve the current set of mysql users
def self.instances
dbs = []

cmd = "#{command(:mysql)} mysql -NBe 'show databases'"
cmd = "HOME='/root' #{mysql} mysql -NBe 'show databases'"
execpipe(cmd) do |process|
process.each do |line|
dbs << new( { :ensure => :present, :name => line.chomp } )
Expand All @@ -26,7 +47,7 @@ def query
:ensure => :absent
}

cmd = "#{command(:mysql)} mysql -NBe 'show databases'"
cmd = "HOME='/root' #{mysql} mysql -NBe 'show databases'"
execpipe(cmd) do |process|
process.each do |line|
if line.chomp.eql?(@resource[:name])
Expand All @@ -38,14 +59,14 @@ def query
end

def create
mysqladmin "create", @resource[:name]
execute_home [mysqladmin, "create", @resource[:name]]
end
def destroy
mysqladmin "-f", "drop", @resource[:name]
execute_home [mysqladmin, "-f", "drop", @resource[:name]]
end

def exists?
if mysql("mysql", "-NBe", "show databases").match(/^#{@resource[:name]}$/)
if execute_home([mysql, "mysql", "-NBe", "show databases"]).match(/^#{@resource[:name]}$/)
true
else
false
Expand Down
42 changes: 30 additions & 12 deletions lib/puppet/provider/mysql_grant/mysql.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- tab-width: 4; ruby-indent-level: 4; indent-tabs-mode: t -*-
# A grant is either global or per-db. This can be distinguished by the syntax
# of the name:
# user@host => global
Expand All @@ -24,11 +25,28 @@

desc "Uses mysql as database."

commands :mysqladmin => 'HOME="/root" /usr/bin/mysqladmin'
commands :mysql => 'HOME="/root" /usr/bin/mysql'
# this is a bit of a hack.
# Since puppet evaluates what provider to use at start time rather than run time
# we can't specify that commands will exist. Instead we call manually.
# I would make these call execute directly, but execpipe needs the path
def mysqladmin
'/usr/bin/mysqladmin'
end
def mysql
'/usr/bin/mysql'
end

def execute_home(command, options = {})
default_options = {
:custom_environment => {}
}
options = default_options.merge(options)
options[:custom_environment][:HOME] = '/root'
execute(command, options)
end

def mysql_flush
mysqladmin "flush-privileges"
execute_home([mysqladmin, "flush-privileges"])
end

# this parses the
Expand Down Expand Up @@ -56,20 +74,20 @@ def create_row
name = split_name(@resource[:name])
case name[:type]
when :user
mysql "mysql", "-e", "INSERT INTO user (host, user) VALUES ('%s', '%s')" % [
execute_home [mysql, "mysql", "-e", "INSERT INTO user (host, user) VALUES ('%s', '%s')" % [
name[:host], name[:user],
]
]]
when :db
mysql "mysql", "-e", "INSERT INTO db (host, user, db) VALUES ('%s', '%s', '%s')" % [
execute_home [mysql, "mysql", "-e", "INSERT INTO db (host, user, db) VALUES ('%s', '%s', '%s')" % [
name[:host], name[:user], name[:db],
]
]]
end
mysql_flush
end
end

def destroy
mysql "mysql", "-e", "REVOKE ALL ON '%s'.* FROM '%s@%s'" % [ @resource[:privileges], @resource[:database], @resource[:name], @resource[:host] ]
execute_home [mysql, "mysql", "-e", "REVOKE ALL ON '%s'.* FROM '%s@%s'" % [ @resource[:privileges], @resource[:database], @resource[:name], @resource[:host] ]]
end

def row_exists?
Expand All @@ -78,7 +96,7 @@ def row_exists?
if name[:type] == :db
fields << :db
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?
not execute_home([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

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

case name[:type]
when :user
privs = mysql "mysql", "-Be", 'select * from user where user="%s" and host="%s"' % [ name[:user], name[:host] ]
privs = execute_home [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] ]
privs = execute_home [mysql, "mysql", "-Be", 'select * from db where user="%s" and host="%s" and db="%s"' % [ name[:user], name[:host], name[:db] ]]
end

if privs.match(/^$/)
Expand Down Expand Up @@ -148,7 +166,7 @@ def privileges=(privs)
# puts "set:", set
stmt = stmt << set << where

mysql "mysql", "-Be", stmt
execute_home [mysql, "mysql", "-Be", stmt]
mysql_flush
end
end
Expand Down
54 changes: 40 additions & 14 deletions lib/puppet/provider/mysql_user/mysql.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,39 @@
require 'puppet/provider/package'

Puppet::Type.type(:mysql_user).provide(:mysql,
# T'is funny business, this code is quite generic
:parent => Puppet::Provider::Package) do
# -*- tab-width: 4; ruby-indent-level: 4; indent-tabs-mode: t -*-
require 'puppet/provider/package.rb'
Puppet::Type.type(:mysql_user).provide :mysql, :parent => Puppet::Provider::Package do

desc "Use mysql as database."
commands :mysql => 'HOME="/root" /usr/bin/mysql'
commands :mysqladmin => 'HOME="/root" /usr/bin/mysqladmin'
# this is a bit of a hack.
# Since puppet evaluates what provider to use at start time rather than run time
# we can't specify that commands will exist. Instead we call manually.
# I would make these call execute directly, but execpipe needs the path
def self.mysqladmin
'/usr/bin/mysqladmin'
end
def self.mysql
'/usr/bin/mysql'
end
def mysqladmin
self.class.mysqladmin
end
def mysql
self.class.mysql
end

def execute_home(command, options = {})
default_options = {
:custom_environment => {}
}
options = default_options.merge(options)
options[:custom_environment][:HOME] = '/root'
execute(command, options)
end

# retrieve the current set of mysql users
def self.instances
users = []

cmd = "#{command(:mysql)} mysql -NBe 'select concat(user, \"@\", host), password from user'"
cmd = "HOME='/root' #{mysql} mysql -NBe 'select concat(user, \"@\", host), password from user'"
execpipe(cmd) do |process|
process.each do |line|
users << new( query_line_to_hash(line) )
Expand All @@ -31,13 +52,13 @@ def self.query_line_to_hash(line)
end

def mysql_flush
mysqladmin "flush-privileges"
execute_home([mysqladmin, "flush-privileges"])
end

def query
result = {}

cmd = "#{command(:mysql)} -NBe 'select concat(user, \"@\", host), password from user where concat(user, \"@\", host) = \"%s\"'" % @resource[:name]
cmd = "HOME='/root' #{mysql} -NBe 'select concat(user, \"@\", host), password from user where concat(user, \"@\", host) = \"%s\"'" % @resource[:name]
execpipe(cmd) do |process|
process.each do |line|
unless result.empty?
Expand All @@ -51,25 +72,30 @@ def query
end

def create
mysql "mysql", "-e", "create user '%s' identified by PASSWORD '%s'" % [ @resource[:name].sub("@", "'@'"), @resource.should(:password_hash) ]
# There is a longstanding MySQL bug where a user that does not appear to exist (previously deleted, etc) still cannot be created.
# http://bugs.mysql.com/bug.php?id=28331
# A workaround is to unconditionally drop the user and ignore the return value
execute_home([mysql, "mysql", "-e", "drop user '%s'" % [ @resource[:name].sub("@", "'@'") ]],
{:failonfail => false})
execute_home [mysql, "mysql", "-e", "create user '%s' identified by PASSWORD '%s'" % [ @resource[:name].sub("@", "'@'"), @resource.should(:password_hash) ]]
mysql_flush
end

def destroy
mysql "mysql", "-e", "drop user '%s'" % @resource[:name].sub("@", "'@'")
execute_home [mysql, "mysql", "-e", "drop user '%s'" % @resource[:name].sub("@", "'@'")]
mysql_flush
end

def exists?
not mysql("mysql", "-NBe", "select '1' from user where CONCAT(user, '@', host) = '%s'" % @resource[:name]).empty?
not execute_home([mysql, "mysql", "-NBe", "select '1' from user where CONCAT(user, '@', host) = '%s'" % @resource[:name]]).empty?
end

def password_hash
@property_hash[:password_hash]
end

def password_hash=(string)
mysql "mysql", "-e", "SET PASSWORD FOR '%s' = '%s'" % [ @resource[:name].sub("@", "'@'"), string ]
execute_home [mysql, "mysql", "-e", "SET PASSWORD FOR '%s' = '%s'" % [ @resource[:name].sub("@", "'@'"), string ]]
mysql_flush
end
end
Expand Down
8 changes: 8 additions & 0 deletions lib/puppet/type/mysql_database.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- tab-width: 4; ruby-indent-level: 4; indent-tabs-mode: t -*-
# This has to be a separate type to enable collecting
Puppet::Type.newtype(:mysql_database) do
@doc = "Manage a database."
Expand All @@ -7,5 +8,12 @@

# TODO: only [[:alnum:]_] allowed
end

autorequire(:service) do
["mysql"]
end
autorequire(:mysql_user) do
["mysql root"]
end
end

9 changes: 9 additions & 0 deletions lib/puppet/type/mysql_grant.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- tab-width: 4; ruby-indent-level: 4; indent-tabs-mode: t -*-
# This has to be a separate type to enable collecting
Puppet::Type.newtype(:mysql_grant) do
@doc = "Manage a database user's rights."
Expand Down Expand Up @@ -73,5 +74,13 @@ def insync?(is)
end

end

autorequire(:service) do
["mysql"]
end

autorequire(:file) do
["/root/.my.cnf"]
end
end

11 changes: 11 additions & 0 deletions lib/puppet/type/mysql_user.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- tab-width: 4; ruby-indent-level: 4; indent-tabs-mode: t -*-
# This has to be a separate type to enable collecting
Puppet::Type.newtype(:mysql_user) do
@doc = "Manage a database user."
Expand All @@ -18,5 +19,15 @@
newproperty(:password_hash) do
desc "The password hash of the user. Use mysql_password() for creating such a hash."
end

autorequire(:service) do
["mysql"]
end
autorequire(:exec) do
["Initialize MySQL server root password"]
end
autorequire(:file) do
["/root/.my.cnf"]
end
end

2 changes: 1 addition & 1 deletion manifests/client.pp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

package { "mysql-client":
ensure => present,
name => $operatingsystem ? {
name => $::operatingsystem ? {
/Debian|Ubuntu|kFreeBSD/ => "mysql-client",
/RedHat|Fedora|CentOS/ => "mysql",
},
Expand Down
8 changes: 3 additions & 5 deletions manifests/database.pp
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
define mysql::database($ensure) {

if $mysql_exists == "true" {
mysql_database { $name:
ensure => $ensure,
require => File["/root/.my.cnf"],
}
mysql_database { $name:
ensure => $ensure,
require => [ File["/root/.my.cnf"], Service['mysql'], ],
}
}
4 changes: 2 additions & 2 deletions manifests/params.pp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class mysql::params {

$mycnf = $operatingsystem ? {
$mycnf = $::operatingsystem ? {
/RedHat|Fedora|CentOS/ => "/etc/my.cnf",
default => "/etc/mysql/my.cnf",
}
Expand All @@ -23,7 +23,7 @@
}

$logfile_group = $mysql_logfile_group ? {
'' => $operatingsystem ? {
'' => $::operatingsystem ? {
'RedHat' => 'mysql',
'Debian' => 'adm',
default => 'adm',
Expand Down
16 changes: 11 additions & 5 deletions manifests/rights.pp
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,25 @@
- *$priv*: target privileges, defaults to "all" (values are the fieldnames from mysql.db table).
*/
define mysql::rights($database, $user, $password, $host="localhost", $ensure="present", $priv="all") {

if $mysql_exists == "true" and $ensure == "present" {
define mysql::rights(
$database,
$user,
$password,
$host="localhost",
$ensure="present",
$priv="all"
) {

if "${::mysql_exists}" == "true" {
if ! defined(Mysql_user ["${user}@${host}"]) {
mysql_user { "${user}@${host}":
ensure => $ensure,
password_hash => mysql_password($password),
require => File["/root/.my.cnf"],
}
}

mysql_grant { "${user}@${host}/${database}":
privileges => $priv,
require => File["/root/.my.cnf"],
}
}

Expand Down
Loading

0 comments on commit 19d7eed

Please sign in to comment.